blob: 7f71701d3c19b397bb548c25ed2af0944158fc4d [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 K. Bainbridge157bdab2020-01-16 14:38:05 -080022 "github.com/golang/protobuf/ptypes/empty"
Jonathan Hart828908c2020-04-15 14:23:45 -070023 ofp "github.com/opencord/goloxi/of13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080024 "github.com/opencord/ofagent-go/internal/pkg/openflow"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000025 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Andrea Campanelladec47f92021-05-27 15:32:45 +020026 "github.com/opencord/voltha-protos/v5/go/openflow_13"
David K. Bainbridge157bdab2020-01-16 14:38:05 -080027 "google.golang.org/grpc"
Andrea Campanelladec47f92021-05-27 15:32:45 +020028 "net"
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 K. Bainbridgee05cf0c2021-08-19 03:16:50 +000048 vc := ofa.volthaClient.Get()
49 if vc == nil {
50 logger.Error(ctx, "No client found to establish Receive Change Event Stream")
51 return
52 }
53 stream, err := vc.ReceiveChangeEvents(streamCtx, &empty.Empty{}, opt)
David K. Bainbridge157bdab2020-01-16 14:38:05 -080054 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000055 logger.Errorw(ctx, "Unable to establish Receive Change Event Stream",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080056 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080057 return
David K. Bainbridge157bdab2020-01-16 14:38:05 -080058 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -080059
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080060top:
David K. Bainbridge157bdab2020-01-16 14:38:05 -080061 for {
62 select {
63 case <-ctx.Done():
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080064 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080065 default:
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080066 ce, err := stream.Recv()
67 if err != nil {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000068 logger.Errorw(ctx, "error receiving change event",
David K. Bainbridge157bdab2020-01-16 14:38:05 -080069 log.Fields{"error": err})
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080070 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080071 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080072 ofa.changeEventChannel <- ce
Rohan Agrawalc32d9932020-06-15 11:01:47 +000073 logger.Debug(ctx, "receive-change-event-queued")
David K. Bainbridge157bdab2020-01-16 14:38:05 -080074 }
75 }
76}
77
78func (ofa *OFAgent) handleChangeEvents(ctx context.Context) {
Rohan Agrawalc32d9932020-06-15 11:01:47 +000079 logger.Debug(ctx, "handle-change-event-started")
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080080
81top:
David K. Bainbridge157bdab2020-01-16 14:38:05 -080082 for {
83 select {
84 case <-ctx.Done():
David K. Bainbridge9cb404e2020-01-28 14:32:29 -080085 break top
David K. Bainbridge157bdab2020-01-16 14:38:05 -080086 case changeEvent := <-ofa.changeEventChannel:
87 deviceID := changeEvent.GetId()
Manindere2af7e42020-12-04 11:46:26 +053088 if errMsg := changeEvent.GetError(); errMsg != nil {
89 logger.Debugw(ctx, "received-change-event",
90 log.Fields{
91 "device-id": deviceID,
92 "error": errMsg})
David K. Bainbridge157bdab2020-01-16 14:38:05 -080093
Andrea Campanelladec47f92021-05-27 15:32:45 +020094 header := errMsg.Header
Manindere2af7e42020-12-04 11:46:26 +053095 ofErrMsg := ofp.NewFlowModFailedErrorMsg()
96
97 ofErrMsg.SetXid(header.Xid)
Andrea Campanella111fc342021-01-29 09:45:45 +010098 ofErrMsg.SetCode(ofp.FlowModFailedCode(errMsg.Code))
99
Manindere2af7e42020-12-04 11:46:26 +0530100 if header.Version != 0 {
101 ofErrMsg.SetVersion(uint8(header.Version))
102 } else {
103 ofErrMsg.SetVersion(4)
104 }
Manindere2af7e42020-12-04 11:46:26 +0530105 ofErrMsg.SetData(errMsg.Data)
Manindere2af7e42020-12-04 11:46:26 +0530106 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofErrMsg); err != nil {
107 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
108 }
109
110 } else if portStatus := changeEvent.GetPortStatus(); portStatus != nil {
111 logger.Debugw(ctx, "received-change-event",
112 log.Fields{
113 "device-id": deviceID,
114 "port-status": portStatus})
115 ofPortStatus := ofp.NewPortStatus()
116 ofPortStatus.SetXid(openflow.GetXid())
117 ofPortStatus.SetVersion(4)
118
119 ofReason := ofp.PortReason(portStatus.GetReason())
120 ofPortStatus.SetReason(ofReason)
121 ofDesc := ofp.NewPortDesc()
122
123 desc := portStatus.GetDesc()
124 ofDesc.SetAdvertised(ofp.PortFeatures(desc.GetAdvertised()))
125 ofDesc.SetConfig(ofp.PortConfig(0))
126 ofDesc.SetCurr(ofp.PortFeatures(desc.GetAdvertised()))
127 ofDesc.SetCurrSpeed(desc.GetCurrSpeed())
128 intArray := desc.GetHwAddr()
129 var octets []byte
130 for _, val := range intArray {
131 octets = append(octets, byte(val))
132 }
133 addr := net.HardwareAddr(octets)
134 ofDesc.SetHwAddr(addr)
135 ofDesc.SetMaxSpeed(desc.GetMaxSpeed())
136 ofDesc.SetName(openflow.PadString(desc.GetName(), 16))
137 ofDesc.SetPeer(ofp.PortFeatures(desc.GetPeer()))
138 ofDesc.SetPortNo(ofp.Port(desc.GetPortNo()))
139 ofDesc.SetState(ofp.PortState(desc.GetState()))
140 ofDesc.SetSupported(ofp.PortFeatures(desc.GetSupported()))
141 ofPortStatus.SetDesc(*ofDesc)
142 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofPortStatus); err != nil {
143 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
144 }
Andrea Campanelladec47f92021-05-27 15:32:45 +0200145 } else if deviceStatus := changeEvent.GetDeviceStatus(); deviceStatus != nil {
146 if deviceStatus.Status == openflow_13.OfpDeviceConnection_OFPDEV_DISCONNECTED {
147 logger.Debugw(ctx, "received-device-disconnect",
148 log.Fields{
149 "device-id": deviceID})
150 ofa.mapLock.Lock()
151 ofa.clientMap[deviceID].Stop()
152 delete(ofa.clientMap, deviceID)
153 ofa.mapLock.Unlock()
154 }
Manindere2af7e42020-12-04 11:46:26 +0530155 } else {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800156 if logger.V(log.WarnLevel) {
157 js, _ := json.Marshal(changeEvent.GetEvent())
Manindere2af7e42020-12-04 11:46:26 +0530158 logger.Warnw(ctx, "Received change event that was neither port status nor error message.",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800159 log.Fields{"ChangeEvent": js})
160 }
161 break
162 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800163 }
164 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800165
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000166 logger.Debug(ctx, "handle-change-event-finsihed")
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800167}