blob: f65c6d929b4e98770ecc66060d8ce8b58f953408 [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"
Maninder12b909f2020-10-23 14:23:36 +053027 "github.com/opencord/voltha-lib-go/v4/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)
93 if header.Version != 0 {
94 ofErrMsg.SetVersion(uint8(header.Version))
95 } else {
96 ofErrMsg.SetVersion(4)
97 }
98
99 ofErrMsg.SetType(uint8(errMsg.Header.Type))
100 ofErrMsg.SetCode(ofp.FlowModFailedCode(errMsg.Code))
101 ofErrMsg.SetData(errMsg.Data)
102
103 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofErrMsg); err != nil {
104 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
105 }
106
107 } else if portStatus := changeEvent.GetPortStatus(); portStatus != nil {
108 logger.Debugw(ctx, "received-change-event",
109 log.Fields{
110 "device-id": deviceID,
111 "port-status": portStatus})
112 ofPortStatus := ofp.NewPortStatus()
113 ofPortStatus.SetXid(openflow.GetXid())
114 ofPortStatus.SetVersion(4)
115
116 ofReason := ofp.PortReason(portStatus.GetReason())
117 ofPortStatus.SetReason(ofReason)
118 ofDesc := ofp.NewPortDesc()
119
120 desc := portStatus.GetDesc()
121 ofDesc.SetAdvertised(ofp.PortFeatures(desc.GetAdvertised()))
122 ofDesc.SetConfig(ofp.PortConfig(0))
123 ofDesc.SetCurr(ofp.PortFeatures(desc.GetAdvertised()))
124 ofDesc.SetCurrSpeed(desc.GetCurrSpeed())
125 intArray := desc.GetHwAddr()
126 var octets []byte
127 for _, val := range intArray {
128 octets = append(octets, byte(val))
129 }
130 addr := net.HardwareAddr(octets)
131 ofDesc.SetHwAddr(addr)
132 ofDesc.SetMaxSpeed(desc.GetMaxSpeed())
133 ofDesc.SetName(openflow.PadString(desc.GetName(), 16))
134 ofDesc.SetPeer(ofp.PortFeatures(desc.GetPeer()))
135 ofDesc.SetPortNo(ofp.Port(desc.GetPortNo()))
136 ofDesc.SetState(ofp.PortState(desc.GetState()))
137 ofDesc.SetSupported(ofp.PortFeatures(desc.GetSupported()))
138 ofPortStatus.SetDesc(*ofDesc)
139 if err := ofa.getOFClient(ctx, deviceID).SendMessage(ctx, ofPortStatus); err != nil {
140 logger.Errorw(ctx, "handle-change-events-send-message", log.Fields{"error": err})
141 }
142 } else {
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800143 if logger.V(log.WarnLevel) {
144 js, _ := json.Marshal(changeEvent.GetEvent())
Manindere2af7e42020-12-04 11:46:26 +0530145 logger.Warnw(ctx, "Received change event that was neither port status nor error message.",
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800146 log.Fields{"ChangeEvent": js})
147 }
148 break
149 }
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800150 }
151 }
David K. Bainbridge9cb404e2020-01-28 14:32:29 -0800152
Rohan Agrawalc32d9932020-06-15 11:01:47 +0000153 logger.Debug(ctx, "handle-change-event-finsihed")
David K. Bainbridge157bdab2020-01-16 14:38:05 -0800154}