blob: 6ea7f12673064b5b349c0003121830ac3a12069d [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"
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000027 "github.com/opencord/voltha-lib-go/v7/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 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})
93 header := errMsg.Header
David K. Bainbridge157bdab2020-01-16 14:38:05 -080094
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 }
145 } else {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800146 if logger.V(log.WarnLevel) {
147 js, _ := json.Marshal(changeEvent.GetEvent())
Manindere2af7e42020-12-04 11:46:26 +0530148 logger.Warnw(ctx, "Received change event that was neither port status nor error message.",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800149 log.Fields{"ChangeEvent": js})
150 }
151 break
152 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800153 }
154 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800155
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000156 logger.Debug(ctx, "handle-change-event-finsihed")
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800157}