blob: f9fa98e03b70e2678bd925fa7d1187f632231d34 [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 ofagent
18
19import (
20 "context"
21 "encoding/json"
David Bainbridgef8ce7d22020-04-08 12:49:41 -070022 "net"
23
David K. Bainbridge157bdab2020-01-16 14:38:05 -080024 "github.com/golang/protobuf/ptypes/empty"
Jonathan Hart828908c2020-04-15 14:23:45 -070025 ofp "github.com/opencord/goloxi/of13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080026 "github.com/opencord/ofagent-go/internal/pkg/openflow"
Andrea Campanella18448bc2021-07-08 18:47:22 +020027 "github.com/opencord/voltha-lib-go/v5/pkg/log"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080028 "google.golang.org/grpc"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080029)
30
31func (ofa *OFAgent) receiveChangeEvents(ctx context.Context) {
Girish Kumar01e0c632020-08-10 16:48:56 +000032 span, ctx := log.CreateChildSpan(ctx, "receive-change-events")
33 defer span.Finish()
34
Rohan Agrawalc32d9932020-06-15 11:01:47 +000035 logger.Debug(ctx, "receive-change-events-started")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080036 // If we exit, assume disconnected
37 defer func() {
38 ofa.events <- ofaEventVolthaDisconnected
Rohan Agrawalc32d9932020-06-15 11:01:47 +000039 logger.Debug(ctx, "receive-change-events-finished")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080040 }()
41 if ofa.volthaClient == nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000042 logger.Error(ctx, "no-voltha-connection")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080043 return
44 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -080045 opt := grpc.EmptyCallOption{}
Girish Kumarcd402012020-08-18 12:17:38 +000046 streamCtx, streamDone := context.WithCancel(log.WithSpanFromContext(context.Background(), ctx))
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080047 defer streamDone()
David Bainbridgef8ce7d22020-04-08 12:49:41 -070048 stream, err := ofa.volthaClient.Get().ReceiveChangeEvents(streamCtx, &empty.Empty{}, opt)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080049 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000050 logger.Errorw(ctx, "Unable to establish Receive Change Event Stream",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080051 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080052 return
David K. Bainbridge157bdab2020-01-16 14:38:05 -080053 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -080054
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080055top:
David K. Bainbridge157bdab2020-01-16 14:38:05 -080056 for {
57 select {
58 case <-ctx.Done():
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080059 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080060 default:
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080061 ce, err := stream.Recv()
62 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000063 logger.Errorw(ctx, "error receiving change event",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080064 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080065 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080066 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080067 ofa.changeEventChannel <- ce
Rohan Agrawalc32d9932020-06-15 11:01:47 +000068 logger.Debug(ctx, "receive-change-event-queued")
David K. Bainbridge157bdab2020-01-16 14:38:05 -080069 }
70 }
71}
72
73func (ofa *OFAgent) handleChangeEvents(ctx context.Context) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000074 logger.Debug(ctx, "handle-change-event-started")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080075
76top:
David K. Bainbridge157bdab2020-01-16 14:38:05 -080077 for {
78 select {
79 case <-ctx.Done():
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080080 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080081 case changeEvent := <-ofa.changeEventChannel:
82 deviceID := changeEvent.GetId()
Manindere2af7e42020-12-04 11:46:26 +053083 if errMsg := changeEvent.GetError(); errMsg != nil {
84 logger.Debugw(ctx, "received-change-event",
85 log.Fields{
86 "device-id": deviceID,
87 "error": errMsg})
88 header := errMsg.Header
David K. Bainbridge157bdab2020-01-16 14:38:05 -080089
Manindere2af7e42020-12-04 11:46:26 +053090 ofErrMsg := ofp.NewFlowModFailedErrorMsg()
91
92 ofErrMsg.SetXid(header.Xid)
Andrea Campanella111fc342021-01-29 09:45:45 +010093 ofErrMsg.SetCode(ofp.FlowModFailedCode(errMsg.Code))
94
Manindere2af7e42020-12-04 11:46:26 +053095 if header.Version != 0 {
96 ofErrMsg.SetVersion(uint8(header.Version))
97 } else {
98 ofErrMsg.SetVersion(4)
99 }
Manindere2af7e42020-12-04 11:46:26 +0530100 ofErrMsg.SetData(errMsg.Data)
Manindere2af7e42020-12-04 11:46:26 +0530101 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofErrMsg); err != nil {
102 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
103 }
104
105 } else if portStatus := changeEvent.GetPortStatus(); portStatus != nil {
106 logger.Debugw(ctx, "received-change-event",
107 log.Fields{
108 "device-id": deviceID,
109 "port-status": portStatus})
110 ofPortStatus := ofp.NewPortStatus()
111 ofPortStatus.SetXid(openflow.GetXid())
112 ofPortStatus.SetVersion(4)
113
114 ofReason := ofp.PortReason(portStatus.GetReason())
115 ofPortStatus.SetReason(ofReason)
116 ofDesc := ofp.NewPortDesc()
117
118 desc := portStatus.GetDesc()
119 ofDesc.SetAdvertised(ofp.PortFeatures(desc.GetAdvertised()))
120 ofDesc.SetConfig(ofp.PortConfig(0))
121 ofDesc.SetCurr(ofp.PortFeatures(desc.GetAdvertised()))
122 ofDesc.SetCurrSpeed(desc.GetCurrSpeed())
123 intArray := desc.GetHwAddr()
124 var octets []byte
125 for _, val := range intArray {
126 octets = append(octets, byte(val))
127 }
128 addr := net.HardwareAddr(octets)
129 ofDesc.SetHwAddr(addr)
130 ofDesc.SetMaxSpeed(desc.GetMaxSpeed())
131 ofDesc.SetName(openflow.PadString(desc.GetName(), 16))
132 ofDesc.SetPeer(ofp.PortFeatures(desc.GetPeer()))
133 ofDesc.SetPortNo(ofp.Port(desc.GetPortNo()))
134 ofDesc.SetState(ofp.PortState(desc.GetState()))
135 ofDesc.SetSupported(ofp.PortFeatures(desc.GetSupported()))
136 ofPortStatus.SetDesc(*ofDesc)
137 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofPortStatus); err != nil {
138 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
139 }
140 } else {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800141 if logger.V(log.WarnLevel) {
142 js, _ := json.Marshal(changeEvent.GetEvent())
Manindere2af7e42020-12-04 11:46:26 +0530143 logger.Warnw(ctx, "Received change event that was neither port status nor error message.",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800144 log.Fields{"ChangeEvent": js})
145 }
146 break
147 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800148 }
149 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800150
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000151 logger.Debug(ctx, "handle-change-event-finsihed")
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800152}