blob: e4b85668d5aec9824bd5eb8e29f5713f131ae94b [file] [log] [blame]
Don Newtone0d34a82019-11-14 10:58:06 -05001/*
David K. Bainbridge157bdab2020-01-16 14:38:05 -08002Copyright 2020 the original author or authors.
Don Newtone0d34a82019-11-14 10:58:06 -05003
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*/
16package openflow
17
18import (
Andrea Campanella07e94942020-07-20 17:35:46 +020019 "encoding/binary"
Don Newtone0d34a82019-11-14 10:58:06 -050020 "encoding/json"
Andrea Campanella07e94942020-07-20 17:35:46 +020021 "unsafe"
David Bainbridgef8ce7d22020-04-08 12:49:41 -070022
Jonathan Hart828908c2020-04-15 14:23:45 -070023 ofp "github.com/opencord/goloxi/of13"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000024 "github.com/opencord/voltha-lib-go/v7/pkg/log"
25 "github.com/opencord/voltha-protos/v5/go/openflow_13"
Don Newtone0d34a82019-11-14 10:58:06 -050026 "golang.org/x/net/context"
Don Newtone0d34a82019-11-14 10:58:06 -050027)
28
Rohan Agrawalc32d9932020-06-15 11:01:47 +000029func (ofc *OFConnection) handleMeterModRequest(ctx context.Context, request *ofp.MeterMod) {
Girish Kumar01e0c632020-08-10 16:48:56 +000030 span, ctx := log.CreateChildSpan(ctx, "openflow-meter-modification")
31 defer span.Finish()
32
David K. Bainbridge157bdab2020-01-16 14:38:05 -080033 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -050034 js, _ := json.Marshal(request)
Rohan Agrawalc32d9932020-06-15 11:01:47 +000035 logger.Debugw(ctx, "handleMeterModRequest called",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080036 log.Fields{
37 "device-id": ofc.DeviceID,
38 "request": js})
Don Newton7577f072020-01-06 12:41:11 -050039 }
Don Newtone0d34a82019-11-14 10:58:06 -050040
David Bainbridgef8ce7d22020-04-08 12:49:41 -070041 volthaClient := ofc.VolthaClient.Get()
42 if volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000043 logger.Errorw(ctx, "no-voltha-connection",
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080044 log.Fields{"device-id": ofc.DeviceID})
45 return
46 }
47
David K. Bainbridge157bdab2020-01-16 14:38:05 -080048 meterModUpdate := openflow_13.MeterModUpdate{Id: ofc.DeviceID}
49 meterMod := openflow_13.OfpMeterMod{
50 MeterId: request.MeterId,
51 Flags: uint32(request.Flags),
52 Command: openflow_13.OfpMeterModCommand(request.Command),
53 }
Don Newtone0d34a82019-11-14 10:58:06 -050054 var bands []*openflow_13.OfpMeterBandHeader
David K. Bainbridge157bdab2020-01-16 14:38:05 -080055 for _, ofpBand := range request.GetMeters() {
Don Newtone0d34a82019-11-14 10:58:06 -050056 var band openflow_13.OfpMeterBandHeader
David K. Bainbridge157bdab2020-01-16 14:38:05 -080057 switch ofpBand.GetType() {
Don Newtone0d34a82019-11-14 10:58:06 -050058 case ofp.OFPMBTDrop:
59 ofpDrop := ofpBand.(ofp.IMeterBandDrop)
Don Newtone0d34a82019-11-14 10:58:06 -050060 band.Type = openflow_13.OfpMeterBandType_OFPMBT_DROP
61 band.Rate = ofpDrop.GetRate()
Don Newtonb437c6f2019-12-18 11:51:57 -050062 band.BurstSize = ofpDrop.GetBurstSize()
Don Newtone0d34a82019-11-14 10:58:06 -050063 case ofp.OFPMBTDSCPRemark:
64 ofpDscpRemark := ofpBand.(ofp.IMeterBandDscpRemark)
65 var dscpRemark openflow_13.OfpMeterBandDscpRemark
66 band.Type = openflow_13.OfpMeterBandType_OFPMBT_DSCP_REMARK
67 band.BurstSize = ofpDscpRemark.GetBurstSize()
68 band.Rate = ofpDscpRemark.GetRate()
69 dscpRemark.PrecLevel = uint32(ofpDscpRemark.GetPrecLevel())
Don Newtonb437c6f2019-12-18 11:51:57 -050070 /*
71 var meterBandHeaderDscp openflow_13.OfpMeterBandHeader_DscpRemark
72 meterBandHeaderDscp.DscpRemark = &dscpRemark
73 band.Data = &meterBandHeaderDscp
74
75 */
Don Newtone0d34a82019-11-14 10:58:06 -050076 case ofp.OFPMBTExperimenter:
77 ofpExperimenter := ofpBand.(ofp.IMeterBandExperimenter)
78 var experimenter openflow_13.OfpMeterBandExperimenter
79 experimenter.Experimenter = ofpExperimenter.GetExperimenter()
80 band.Type = openflow_13.OfpMeterBandType_OFPMBT_EXPERIMENTER
81 band.BurstSize = ofpExperimenter.GetBurstSize()
82 band.Rate = ofpExperimenter.GetRate()
Don Newtonb437c6f2019-12-18 11:51:57 -050083 /*
84 var meterBandHeaderExperimenter openflow_13.OfpMeterBandHeader_Experimenter
85 meterBandHeaderExperimenter.Experimenter = &experimenter
86 band.Data = &meterBandHeaderExperimenter
87
88 */
Don Newtone0d34a82019-11-14 10:58:06 -050089 }
90 bands = append(bands, &band)
91 }
92 meterMod.Bands = bands
93 meterModUpdate.MeterMod = &meterMod
David K. Bainbridge157bdab2020-01-16 14:38:05 -080094 if logger.V(log.DebugLevel) {
Don Newton7577f072020-01-06 12:41:11 -050095 meterModJS, _ := json.Marshal(meterModUpdate)
Rohan Agrawalc32d9932020-06-15 11:01:47 +000096 logger.Debugw(ctx, "handleMeterModUpdate sending request",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080097 log.Fields{
98 "device-id": ofc.DeviceID,
99 "meter-mod-request": meterModJS})
Don Newtone0d34a82019-11-14 10:58:06 -0500100 }
Girish Kumar01e0c632020-08-10 16:48:56 +0000101 if _, err := volthaClient.UpdateLogicalDeviceMeterTable(log.WithSpanFromContext(context.Background(), ctx), &meterModUpdate); err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000102 logger.Errorw(ctx, "Error calling UpdateLogicalDeviceMeterTable",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800103 log.Fields{
104 "device-id": ofc.DeviceID,
105 "error": err})
Andrea Campanella07e94942020-07-20 17:35:46 +0200106 message := ofp.NewMeterModFailedErrorMsg()
107 message.SetXid(request.Xid)
108 //OF 1.3
109 message.SetVersion(4)
110 //FIXME Hardcoding to Invalid Meter for now.
111 message.SetCode(ofp.OFPMMFCInvalidMeter)
112 meterByteId := make([]byte, 4)
113 binary.BigEndian.PutUint32(meterByteId, request.MeterId)
114 message.SetData(meterByteId)
115 message.Length = uint16(unsafe.Sizeof(*message))
116 if err := ofc.SendMessage(ctx, message); err != nil {
117 logger.Errorw(ctx, "Error reporting failure of MeterMod to controller",
118 log.Fields{
119 "device-id": ofc.DeviceID,
120 "error": err})
121 }
Don Newton7577f072020-01-06 12:41:11 -0500122 }
Don Newtone0d34a82019-11-14 10:58:06 -0500123}