blob: a5c47b9f6533dd9011f39c6df669d83e2356d5d2 [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001/*
2 * Copyright 2018-present Open Networking Foundation
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 */
npujar1d86a522019-11-14 17:11:16 +053016
Kent Hagerman2b216042020-04-03 18:28:56 -040017package device
khenaidoob9203542018-09-17 22:56:37 -040018
19import (
20 "context"
21 "errors"
Kent Hagerman45a13e42020-04-13 12:23:50 -040022 "github.com/golang/protobuf/ptypes/empty"
23 "github.com/opencord/voltha-go/rw_core/core/device/event"
Kent Hagerman2b216042020-04-03 18:28:56 -040024 "github.com/opencord/voltha-go/rw_core/utils"
Kent Hagerman45a13e42020-04-13 12:23:50 -040025 "io"
David Bainbridged1afd662020-03-26 18:27:41 -070026 "strings"
27 "sync"
28 "time"
29
sbarbari17d7e222019-11-05 10:02:29 -050030 "github.com/opencord/voltha-go/db/model"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080031 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
32 "github.com/opencord/voltha-lib-go/v3/pkg/log"
33 "github.com/opencord/voltha-lib-go/v3/pkg/probe"
34 "github.com/opencord/voltha-protos/v3/go/openflow_13"
35 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040036 "google.golang.org/grpc/codes"
37 "google.golang.org/grpc/status"
khenaidoob9203542018-09-17 22:56:37 -040038)
39
Kent Hagerman2b216042020-04-03 18:28:56 -040040// LogicalManager represent logical device manager attributes
41type LogicalManager struct {
Kent Hagerman45a13e42020-04-13 12:23:50 -040042 *event.Manager
khenaidoo4c9e5592019-09-09 16:20:41 -040043 logicalDeviceAgents sync.Map
Kent Hagerman2b216042020-04-03 18:28:56 -040044 deviceMgr *Manager
npujar467fe752020-01-16 20:17:45 +053045 kafkaICProxy kafka.InterContainerProxy
khenaidoo4c9e5592019-09-09 16:20:41 -040046 clusterDataProxy *model.Proxy
47 exitChannel chan int
khenaidoo442e7c72020-03-10 16:13:48 -040048 defaultTimeout time.Duration
khenaidoo4c9e5592019-09-09 16:20:41 -040049 logicalDevicesLoadingLock sync.RWMutex
50 logicalDeviceLoadingInProgress map[string][]chan int
khenaidoob9203542018-09-17 22:56:37 -040051}
52
Kent Hagerman2b216042020-04-03 18:28:56 -040053func (ldMgr *LogicalManager) Start(ctx context.Context) {
Girish Kumarf56a4682020-03-20 20:07:46 +000054 logger.Info("starting-logical-device-manager")
David K. Bainbridgeb4a9ab02019-09-20 15:12:16 -070055 probe.UpdateStatusFromContext(ctx, "logical-device-manager", probe.ServiceStatusRunning)
Girish Kumarf56a4682020-03-20 20:07:46 +000056 logger.Info("logical-device-manager-started")
khenaidoob9203542018-09-17 22:56:37 -040057}
58
Kent Hagerman2b216042020-04-03 18:28:56 -040059func (ldMgr *LogicalManager) Stop(ctx context.Context) {
Girish Kumarf56a4682020-03-20 20:07:46 +000060 logger.Info("stopping-logical-device-manager")
khenaidoob9203542018-09-17 22:56:37 -040061 ldMgr.exitChannel <- 1
David K. Bainbridgeb4a9ab02019-09-20 15:12:16 -070062 probe.UpdateStatusFromContext(ctx, "logical-device-manager", probe.ServiceStatusStopped)
Girish Kumarf56a4682020-03-20 20:07:46 +000063 logger.Info("logical-device-manager-stopped")
khenaidoob9203542018-09-17 22:56:37 -040064}
65
Kent Hagerman2b216042020-04-03 18:28:56 -040066func (ldMgr *LogicalManager) addLogicalDeviceAgentToMap(agent *LogicalAgent) {
npujar1d86a522019-11-14 17:11:16 +053067 if _, exist := ldMgr.logicalDeviceAgents.Load(agent.logicalDeviceID); !exist {
68 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceID, agent)
khenaidoob9203542018-09-17 22:56:37 -040069 }
70}
71
khenaidoo8c3303d2019-02-13 14:59:39 -050072// getLogicalDeviceAgent returns the logical device agent. If the device is not in memory then the device will
73// be loaded from dB and a logical device agent created to managed it.
Kent Hagerman2b216042020-04-03 18:28:56 -040074func (ldMgr *LogicalManager) getLogicalDeviceAgent(ctx context.Context, logicalDeviceID string) *LogicalAgent {
Andrea Campanella09400bd2020-04-02 11:58:04 +020075 logger.Debugw("get-logical-device-agent", log.Fields{"logical-device-id": logicalDeviceID})
npujar1d86a522019-11-14 17:11:16 +053076 agent, ok := ldMgr.logicalDeviceAgents.Load(logicalDeviceID)
77 if ok {
Kent Hagerman2b216042020-04-03 18:28:56 -040078 lda := agent.(*LogicalAgent)
khenaidoo93d5a3d2020-01-15 12:37:05 -050079 if lda.logicalDevice == nil {
80 // This can happen when an agent for the logical device has been created but the logical device
81 // itself is not ready for action as it is waiting for switch and port capabilities from the
82 // relevant adapter. In such a case prevent any request aimed at that logical device.
Girish Kumarf56a4682020-03-20 20:07:46 +000083 logger.Debugf("Logical device %s is not ready to serve requests", logicalDeviceID)
khenaidoo93d5a3d2020-01-15 12:37:05 -050084 return nil
85 }
86 return lda
npujar1d86a522019-11-14 17:11:16 +053087 }
88 // Try to load into memory - loading will also create the logical device agent
npujar467fe752020-01-16 20:17:45 +053089 if err := ldMgr.load(ctx, logicalDeviceID); err == nil {
npujar1d86a522019-11-14 17:11:16 +053090 if agent, ok = ldMgr.logicalDeviceAgents.Load(logicalDeviceID); ok {
Kent Hagerman2b216042020-04-03 18:28:56 -040091 return agent.(*LogicalAgent)
khenaidoo8c3303d2019-02-13 14:59:39 -050092 }
khenaidoob9203542018-09-17 22:56:37 -040093 }
94 return nil
95}
96
Kent Hagerman2b216042020-04-03 18:28:56 -040097func (ldMgr *LogicalManager) deleteLogicalDeviceAgent(logicalDeviceID string) {
npujar1d86a522019-11-14 17:11:16 +053098 ldMgr.logicalDeviceAgents.Delete(logicalDeviceID)
khenaidoo92e62c52018-10-03 14:02:54 -040099}
100
khenaidoo8c3303d2019-02-13 14:59:39 -0500101// GetLogicalDevice provides a cloned most up to date logical device. If device is not in memory
102// it will be fetched from the dB
Kent Hagerman45a13e42020-04-13 12:23:50 -0400103func (ldMgr *LogicalManager) GetLogicalDevice(ctx context.Context, id *voltha.ID) (*voltha.LogicalDevice, error) {
Girish Kumarf56a4682020-03-20 20:07:46 +0000104 logger.Debugw("getlogicalDevice", log.Fields{"logicaldeviceid": id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400105 if agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id); agent != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400106 return agent.GetLogicalDevice(ctx)
khenaidoob9203542018-09-17 22:56:37 -0400107 }
108 return nil, status.Errorf(codes.NotFound, "%s", id)
109}
110
Kent Hagerman2b216042020-04-03 18:28:56 -0400111//ListLogicalDevices returns the list of all logical devices
Kent Hagerman45a13e42020-04-13 12:23:50 -0400112func (ldMgr *LogicalManager) ListLogicalDevices(ctx context.Context, _ *empty.Empty) (*voltha.LogicalDevices, error) {
Girish Kumarf56a4682020-03-20 20:07:46 +0000113 logger.Debug("ListAllLogicalDevices")
Kent Hagerman4f355f52020-03-30 16:01:33 -0400114
115 var logicalDevices []*voltha.LogicalDevice
116 if err := ldMgr.clusterDataProxy.List(ctx, "logical_devices", &logicalDevices); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000117 logger.Errorw("failed-to-list-logical-devices-from-cluster-proxy", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530118 return nil, err
119 }
Kent Hagerman4f355f52020-03-30 16:01:33 -0400120 return &voltha.LogicalDevices{Items: logicalDevices}, nil
khenaidoob9203542018-09-17 22:56:37 -0400121}
122
Kent Hagerman2b216042020-04-03 18:28:56 -0400123func (ldMgr *LogicalManager) createLogicalDevice(ctx context.Context, device *voltha.Device) (*string, error) {
Girish Kumarf56a4682020-03-20 20:07:46 +0000124 logger.Debugw("creating-logical-device", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400125 // Sanity check
126 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400127 return nil, errors.New("device-not-root")
khenaidoob9203542018-09-17 22:56:37 -0400128 }
129
130 // Create a logical device agent - the logical device Id is based on the mac address of the device
131 // For now use the serial number - it may contain any combination of alphabetic characters and numbers,
132 // with length varying from eight characters to a maximum of 14 characters. Mac Address is part of oneof
133 // in the Device model. May need to be moved out.
Kent Hagerman2b216042020-04-03 18:28:56 -0400134 id := utils.CreateLogicalDeviceID()
David Bainbridged1afd662020-03-26 18:27:41 -0700135 sn := strings.Replace(device.MacAddress, ":", "", -1)
khenaidoo92e62c52018-10-03 14:02:54 -0400136 if id == "" {
David Bainbridged1afd662020-03-26 18:27:41 -0700137 logger.Errorw("mac-address-not-set", log.Fields{"deviceId": device.Id, "serial-number": sn})
khenaidoo92e62c52018-10-03 14:02:54 -0400138 return nil, errors.New("mac-address-not-set")
139 }
David Bainbridged1afd662020-03-26 18:27:41 -0700140
Girish Kumarf56a4682020-03-20 20:07:46 +0000141 logger.Debugw("logical-device-id", log.Fields{"logicaldeviceId": id})
khenaidoob9203542018-09-17 22:56:37 -0400142
David Bainbridged1afd662020-03-26 18:27:41 -0700143 agent := newLogicalDeviceAgent(id, sn, device.Id, ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400144 ldMgr.addLogicalDeviceAgentToMap(agent)
khenaidooad06fd72019-10-28 12:26:05 -0400145
146 // Update the root device with the logical device Id reference
npujar467fe752020-01-16 20:17:45 +0530147 if err := ldMgr.deviceMgr.setParentID(ctx, device, id); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000148 logger.Errorw("failed-setting-parent-id", log.Fields{"logicalDeviceId": id, "deviceId": device.Id})
khenaidooad06fd72019-10-28 12:26:05 -0400149 return nil, err
150 }
151
npujar1d86a522019-11-14 17:11:16 +0530152 go func() {
khenaidoo442e7c72020-03-10 16:13:48 -0400153 //agent := newLogicalDeviceAgent(id, device.Id, ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
154 err := agent.start(context.Background(), false)
npujar1d86a522019-11-14 17:11:16 +0530155 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000156 logger.Errorw("unable-to-create-the-logical-device", log.Fields{"error": err})
khenaidoo442e7c72020-03-10 16:13:48 -0400157 ldMgr.deleteLogicalDeviceAgent(id)
npujar1d86a522019-11-14 17:11:16 +0530158 }
159 }()
khenaidoob9203542018-09-17 22:56:37 -0400160
Girish Kumarf56a4682020-03-20 20:07:46 +0000161 logger.Debug("creating-logical-device-ends")
khenaidoob9203542018-09-17 22:56:37 -0400162 return &id, nil
163}
164
khenaidoo6d62c002019-05-15 21:57:03 -0400165// stopManagingLogicalDeviceWithDeviceId stops the management of the logical device. This implies removal of any
166// reference of this logical device in cache. The device Id is passed as param because the logical device may already
167// have been removed from the model. This function returns the logical device Id if found
Kent Hagerman2b216042020-04-03 18:28:56 -0400168func (ldMgr *LogicalManager) stopManagingLogicalDeviceWithDeviceID(ctx context.Context, id string) string {
Girish Kumarf56a4682020-03-20 20:07:46 +0000169 logger.Infow("stop-managing-logical-device", log.Fields{"deviceId": id})
khenaidoo6d62c002019-05-15 21:57:03 -0400170 // Go over the list of logical device agents to find the one which has rootDeviceId as id
npujar1d86a522019-11-14 17:11:16 +0530171 var ldID = ""
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400172 ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
Kent Hagerman2b216042020-04-03 18:28:56 -0400173 ldAgent := value.(*LogicalAgent)
npujar1d86a522019-11-14 17:11:16 +0530174 if ldAgent.rootDeviceID == id {
Girish Kumarf56a4682020-03-20 20:07:46 +0000175 logger.Infow("stopping-logical-device-agent", log.Fields{"lDeviceId": key})
npujar467fe752020-01-16 20:17:45 +0530176 if err := ldAgent.stop(ctx); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000177 logger.Errorw("failed-to-stop-LDAgent", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530178 return false
179 }
npujar1d86a522019-11-14 17:11:16 +0530180 ldID = key.(string)
181 ldMgr.logicalDeviceAgents.Delete(ldID)
khenaidoo6d62c002019-05-15 21:57:03 -0400182 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400183 return true
184 })
npujar1d86a522019-11-14 17:11:16 +0530185 return ldID
khenaidoo6d62c002019-05-15 21:57:03 -0400186}
187
188//getLogicalDeviceFromModel retrieves the logical device data from the model.
Kent Hagerman2b216042020-04-03 18:28:56 -0400189func (ldMgr *LogicalManager) getLogicalDeviceFromModel(ctx context.Context, lDeviceID string) (*voltha.LogicalDevice, error) {
Kent Hagerman4f355f52020-03-30 16:01:33 -0400190 logicalDevice := &voltha.LogicalDevice{}
191 if have, err := ldMgr.clusterDataProxy.Get(ctx, "logical_devices/"+lDeviceID, logicalDevice); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000192 logger.Errorw("failed-to-get-logical-devices-from-cluster-proxy", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530193 return nil, err
Kent Hagerman4f355f52020-03-30 16:01:33 -0400194 } else if !have {
195 return nil, status.Error(codes.NotFound, lDeviceID)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530196 }
Kent Hagerman4f355f52020-03-30 16:01:33 -0400197
198 return logicalDevice, nil
khenaidoo6d62c002019-05-15 21:57:03 -0400199}
200
khenaidoo297cd252019-02-07 22:10:23 -0500201// load loads a logical device manager in memory
Kent Hagerman2b216042020-04-03 18:28:56 -0400202func (ldMgr *LogicalManager) load(ctx context.Context, lDeviceID string) error {
npujar1d86a522019-11-14 17:11:16 +0530203 if lDeviceID == "" {
khenaidoo4c9e5592019-09-09 16:20:41 -0400204 return nil
khenaidoo297cd252019-02-07 22:10:23 -0500205 }
khenaidoo4c9e5592019-09-09 16:20:41 -0400206 // Add a lock to prevent two concurrent calls from loading the same device twice
207 ldMgr.logicalDevicesLoadingLock.Lock()
npujar1d86a522019-11-14 17:11:16 +0530208 if _, exist := ldMgr.logicalDeviceLoadingInProgress[lDeviceID]; !exist {
209 if ldAgent, _ := ldMgr.logicalDeviceAgents.Load(lDeviceID); ldAgent == nil {
210 ldMgr.logicalDeviceLoadingInProgress[lDeviceID] = []chan int{make(chan int, 1)}
khenaidoo4c9e5592019-09-09 16:20:41 -0400211 ldMgr.logicalDevicesLoadingLock.Unlock()
npujar467fe752020-01-16 20:17:45 +0530212 if _, err := ldMgr.getLogicalDeviceFromModel(ctx, lDeviceID); err == nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000213 logger.Debugw("loading-logical-device", log.Fields{"lDeviceId": lDeviceID})
David Bainbridged1afd662020-03-26 18:27:41 -0700214 agent := newLogicalDeviceAgent(lDeviceID, "", "", ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
npujar467fe752020-01-16 20:17:45 +0530215 if err := agent.start(ctx, true); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400216 return err
khenaidoo4c9e5592019-09-09 16:20:41 -0400217 }
khenaidoo442e7c72020-03-10 16:13:48 -0400218 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceID, agent)
khenaidoo4c9e5592019-09-09 16:20:41 -0400219 } else {
Girish Kumarf56a4682020-03-20 20:07:46 +0000220 logger.Debugw("logicalDevice not in model", log.Fields{"lDeviceId": lDeviceID})
khenaidoo4c9e5592019-09-09 16:20:41 -0400221 }
222 // announce completion of task to any number of waiting channels
223 ldMgr.logicalDevicesLoadingLock.Lock()
npujar1d86a522019-11-14 17:11:16 +0530224 if v, ok := ldMgr.logicalDeviceLoadingInProgress[lDeviceID]; ok {
khenaidoo4c9e5592019-09-09 16:20:41 -0400225 for _, ch := range v {
226 close(ch)
227 }
npujar1d86a522019-11-14 17:11:16 +0530228 delete(ldMgr.logicalDeviceLoadingInProgress, lDeviceID)
khenaidoo4c9e5592019-09-09 16:20:41 -0400229 }
230 ldMgr.logicalDevicesLoadingLock.Unlock()
231 } else {
232 ldMgr.logicalDevicesLoadingLock.Unlock()
233 }
234 } else {
235 ch := make(chan int, 1)
npujar1d86a522019-11-14 17:11:16 +0530236 ldMgr.logicalDeviceLoadingInProgress[lDeviceID] = append(ldMgr.logicalDeviceLoadingInProgress[lDeviceID], ch)
khenaidoo4c9e5592019-09-09 16:20:41 -0400237 ldMgr.logicalDevicesLoadingLock.Unlock()
238 // Wait for the channel to be closed, implying the process loading this device is done.
239 <-ch
240 }
npujar1d86a522019-11-14 17:11:16 +0530241 if _, exist := ldMgr.logicalDeviceAgents.Load(lDeviceID); exist {
khenaidoo4c9e5592019-09-09 16:20:41 -0400242 return nil
243 }
npujar1d86a522019-11-14 17:11:16 +0530244 return status.Errorf(codes.Aborted, "Error loading logical device %s", lDeviceID)
khenaidoo297cd252019-02-07 22:10:23 -0500245}
246
Kent Hagerman2b216042020-04-03 18:28:56 -0400247func (ldMgr *LogicalManager) deleteLogicalDevice(ctx context.Context, device *voltha.Device) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000248 logger.Debugw("deleting-logical-device", log.Fields{"deviceId": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400249 // Sanity check
250 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400251 return errors.New("device-not-root")
khenaidoo92e62c52018-10-03 14:02:54 -0400252 }
npujar1d86a522019-11-14 17:11:16 +0530253 logDeviceID := device.ParentId
npujar467fe752020-01-16 20:17:45 +0530254 if agent := ldMgr.getLogicalDeviceAgent(ctx, logDeviceID); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400255 // Stop the logical device agent
Thomas Lee Se5a44012019-11-07 20:32:24 +0530256 if err := agent.stop(ctx); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000257 logger.Errorw("failed-to-stop-agent", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530258 return err
259 }
khenaidoo92e62c52018-10-03 14:02:54 -0400260 //Remove the logical device agent from the Map
npujar1d86a522019-11-14 17:11:16 +0530261 ldMgr.deleteLogicalDeviceAgent(logDeviceID)
khenaidoo92e62c52018-10-03 14:02:54 -0400262 }
263
Girish Kumarf56a4682020-03-20 20:07:46 +0000264 logger.Debug("deleting-logical-device-ends")
khenaidoo92e62c52018-10-03 14:02:54 -0400265 return nil
266}
267
Kent Hagerman2b216042020-04-03 18:28:56 -0400268func (ldMgr *LogicalManager) getLogicalDeviceID(ctx context.Context, device *voltha.Device) (*string, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400269 // Device can either be a parent or a child device
270 if device.Root {
271 // Parent device. The ID of a parent device is the logical device ID
272 return &device.ParentId, nil
273 }
274 // Device is child device
275 // retrieve parent device using child device ID
npujar467fe752020-01-16 20:17:45 +0530276 if parentDevice := ldMgr.deviceMgr.getParentDevice(ctx, device); parentDevice != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400277 return &parentDevice.ParentId, nil
278 }
279 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
280}
281
Kent Hagerman2b216042020-04-03 18:28:56 -0400282func (ldMgr *LogicalManager) getLogicalDeviceIDFromDeviceID(ctx context.Context, deviceID string) (*string, error) {
khenaidoo3ab34882019-05-02 21:33:30 -0400283 // Get the device
284 var device *voltha.Device
285 var err error
Kent Hagerman45a13e42020-04-13 12:23:50 -0400286 if device, err = ldMgr.deviceMgr.getDevice(ctx, deviceID); err != nil {
khenaidoo3ab34882019-05-02 21:33:30 -0400287 return nil, err
288 }
npujar467fe752020-01-16 20:17:45 +0530289 return ldMgr.getLogicalDeviceID(ctx, device)
khenaidoo3ab34882019-05-02 21:33:30 -0400290}
291
Kent Hagerman2b216042020-04-03 18:28:56 -0400292func (ldMgr *LogicalManager) getLogicalPortID(ctx context.Context, device *voltha.Device) (*voltha.LogicalPortId, error) {
khenaidoo19d7b632018-10-30 10:49:50 -0400293 // Get the logical device where this device is attached
npujar1d86a522019-11-14 17:11:16 +0530294 var lDeviceID *string
khenaidoo19d7b632018-10-30 10:49:50 -0400295 var err error
npujar467fe752020-01-16 20:17:45 +0530296 if lDeviceID, err = ldMgr.getLogicalDeviceID(ctx, device); err != nil {
khenaidoo19d7b632018-10-30 10:49:50 -0400297 return nil, err
298 }
299 var lDevice *voltha.LogicalDevice
Kent Hagerman45a13e42020-04-13 12:23:50 -0400300 if lDevice, err = ldMgr.GetLogicalDevice(ctx, &voltha.ID{Id: *lDeviceID}); err != nil {
khenaidoo19d7b632018-10-30 10:49:50 -0400301 return nil, err
302 }
303 // Go over list of ports
304 for _, port := range lDevice.Ports {
305 if port.DeviceId == device.Id {
npujar1d86a522019-11-14 17:11:16 +0530306 return &voltha.LogicalPortId{Id: *lDeviceID, PortId: port.Id}, nil
khenaidoo19d7b632018-10-30 10:49:50 -0400307 }
308 }
309 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
310}
311
npujar1d86a522019-11-14 17:11:16 +0530312// ListLogicalDeviceFlows returns the flows of logical device
Kent Hagerman45a13e42020-04-13 12:23:50 -0400313func (ldMgr *LogicalManager) ListLogicalDeviceFlows(ctx context.Context, id *voltha.ID) (*openflow_13.Flows, error) {
314 logger.Debugw("ListLogicalDeviceFlows", log.Fields{"logicaldeviceid": id.Id})
315 if agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id); agent != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400316 return agent.ListLogicalDeviceFlows(ctx)
khenaidoodd237172019-05-27 16:37:17 -0400317 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400318 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoodd237172019-05-27 16:37:17 -0400319}
320
npujar1d86a522019-11-14 17:11:16 +0530321// ListLogicalDeviceFlowGroups returns logical device flow groups
Kent Hagerman45a13e42020-04-13 12:23:50 -0400322func (ldMgr *LogicalManager) ListLogicalDeviceFlowGroups(ctx context.Context, id *voltha.ID) (*openflow_13.FlowGroups, error) {
323 logger.Debugw("ListLogicalDeviceFlowGroups", log.Fields{"logicaldeviceid": id.Id})
324 if agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id); agent != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400325 return agent.ListLogicalDeviceFlowGroups(ctx)
khenaidoodd237172019-05-27 16:37:17 -0400326 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400327 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoodd237172019-05-27 16:37:17 -0400328}
329
npujar1d86a522019-11-14 17:11:16 +0530330// ListLogicalDevicePorts returns logical device ports
Kent Hagerman45a13e42020-04-13 12:23:50 -0400331func (ldMgr *LogicalManager) ListLogicalDevicePorts(ctx context.Context, id *voltha.ID) (*voltha.LogicalPorts, error) {
332 logger.Debugw("ListLogicalDevicePorts", log.Fields{"logicaldeviceid": id.Id})
333 if agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id); agent != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400334 return agent.ListLogicalDevicePorts(ctx)
khenaidoo19d7b632018-10-30 10:49:50 -0400335 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400336 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400337}
338
Kent Hagerman45a13e42020-04-13 12:23:50 -0400339// GetLogicalDevicePort returns logical device port details
340func (ldMgr *LogicalManager) GetLogicalDevicePort(ctx context.Context, lPortID *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
khenaidoo19d7b632018-10-30 10:49:50 -0400341 // Get the logical device where this device is attached
342 var err error
343 var lDevice *voltha.LogicalDevice
Kent Hagerman45a13e42020-04-13 12:23:50 -0400344 if lDevice, err = ldMgr.GetLogicalDevice(ctx, &voltha.ID{Id: lPortID.Id}); err != nil {
khenaidoo19d7b632018-10-30 10:49:50 -0400345 return nil, err
346 }
347 // Go over list of ports
348 for _, port := range lDevice.Ports {
npujar1d86a522019-11-14 17:11:16 +0530349 if port.Id == lPortID.PortId {
khenaidoo19d7b632018-10-30 10:49:50 -0400350 return port, nil
351 }
352 }
npujar1d86a522019-11-14 17:11:16 +0530353 return nil, status.Errorf(codes.NotFound, "%s-%s", lPortID.Id, lPortID.PortId)
khenaidoo19d7b632018-10-30 10:49:50 -0400354}
355
khenaidoo2c6a0992019-04-29 13:46:56 -0400356// updateLogicalPort sets up a logical port on the logical device based on the device port
357// information, if needed
Kent Hagerman2b216042020-04-03 18:28:56 -0400358func (ldMgr *LogicalManager) updateLogicalPort(ctx context.Context, device *voltha.Device, port *voltha.Port) error {
npujar467fe752020-01-16 20:17:45 +0530359 ldID, err := ldMgr.getLogicalDeviceID(ctx, device)
npujar1d86a522019-11-14 17:11:16 +0530360 if err != nil || *ldID == "" {
khenaidoo2c6a0992019-04-29 13:46:56 -0400361 // This is not an error as the logical device may not have been created at this time. In such a case,
362 // the ports will be created when the logical device is ready.
363 return nil
khenaidoo2c6a0992019-04-29 13:46:56 -0400364 }
npujar467fe752020-01-16 20:17:45 +0530365 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
366 if err := agent.updateLogicalPort(ctx, device, port); err != nil {
npujar1d86a522019-11-14 17:11:16 +0530367 return err
khenaidoofc1314d2019-03-14 09:34:21 -0400368 }
369 }
370 return nil
371}
372
khenaidoo0a822f92019-05-08 15:15:57 -0400373// deleteLogicalPort removes the logical port associated with a device
Kent Hagerman2b216042020-04-03 18:28:56 -0400374func (ldMgr *LogicalManager) deleteLogicalPort(ctx context.Context, lPortID *voltha.LogicalPortId) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000375 logger.Debugw("deleting-logical-port", log.Fields{"LDeviceId": lPortID.Id})
khenaidoo19d7b632018-10-30 10:49:50 -0400376 // Get logical port
377 var logicalPort *voltha.LogicalPort
378 var err error
Kent Hagerman45a13e42020-04-13 12:23:50 -0400379 if logicalPort, err = ldMgr.GetLogicalDevicePort(ctx, lPortID); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000380 logger.Debugw("no-logical-device-port-present", log.Fields{"logicalPortId": lPortID.PortId})
khenaidoo19d7b632018-10-30 10:49:50 -0400381 return err
382 }
khenaidoo92e62c52018-10-03 14:02:54 -0400383 // Sanity check
khenaidoo19d7b632018-10-30 10:49:50 -0400384 if logicalPort.RootPort {
khenaidoo2c6a0992019-04-29 13:46:56 -0400385 return errors.New("device-root")
khenaidoo92e62c52018-10-03 14:02:54 -0400386 }
npujar467fe752020-01-16 20:17:45 +0530387 if agent := ldMgr.getLogicalDeviceAgent(ctx, lPortID.Id); agent != nil {
388 if err := agent.deleteLogicalPort(ctx, logicalPort); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000389 logger.Warnw("deleting-logicalport-failed", log.Fields{"LDeviceId": lPortID.Id, "error": err})
khenaidoo0a822f92019-05-08 15:15:57 -0400390 }
khenaidoo92e62c52018-10-03 14:02:54 -0400391 }
392
Girish Kumarf56a4682020-03-20 20:07:46 +0000393 logger.Debug("deleting-logical-port-ends")
khenaidoo92e62c52018-10-03 14:02:54 -0400394 return nil
395}
396
khenaidoo0a822f92019-05-08 15:15:57 -0400397// deleteLogicalPort removes the logical port associated with a child device
Kent Hagerman2b216042020-04-03 18:28:56 -0400398func (ldMgr *LogicalManager) deleteLogicalPorts(ctx context.Context, deviceID string) error {
Andrea Campanella09400bd2020-04-02 11:58:04 +0200399 logger.Debugw("deleting-logical-ports", log.Fields{"device-id": deviceID})
khenaidoo0a822f92019-05-08 15:15:57 -0400400 // Get logical port
npujar467fe752020-01-16 20:17:45 +0530401 ldID, err := ldMgr.getLogicalDeviceIDFromDeviceID(ctx, deviceID)
npujar1d86a522019-11-14 17:11:16 +0530402 if err != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400403 return err
npujar1d86a522019-11-14 17:11:16 +0530404 }
npujar467fe752020-01-16 20:17:45 +0530405 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
406 if err = agent.deleteLogicalPorts(ctx, deviceID); err != nil {
Andrea Campanella09400bd2020-04-02 11:58:04 +0200407 logger.Warnw("delete-logical-ports-failed", log.Fields{"logical-device-id": *ldID})
npujar1d86a522019-11-14 17:11:16 +0530408 return err
khenaidoo0a822f92019-05-08 15:15:57 -0400409 }
410 }
Andrea Campanella09400bd2020-04-02 11:58:04 +0200411 logger.Debug("deleting-logical-ports-ends")
khenaidoo0a822f92019-05-08 15:15:57 -0400412 return nil
413}
414
Kent Hagerman2b216042020-04-03 18:28:56 -0400415func (ldMgr *LogicalManager) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000416 logger.Debugw("setupUNILogicalPorts", log.Fields{"childDeviceId": childDevice.Id, "parentDeviceId": childDevice.ParentId, "current-data": childDevice})
khenaidoob9203542018-09-17 22:56:37 -0400417 // Sanity check
418 if childDevice.Root {
419 return errors.New("Device-root")
420 }
421
422 // Get the logical device id parent device
npujar1d86a522019-11-14 17:11:16 +0530423 parentID := childDevice.ParentId
npujar467fe752020-01-16 20:17:45 +0530424 logDeviceID := ldMgr.deviceMgr.GetParentDeviceID(ctx, parentID)
khenaidoob9203542018-09-17 22:56:37 -0400425
Girish Kumarf56a4682020-03-20 20:07:46 +0000426 logger.Debugw("setupUNILogicalPorts", log.Fields{"logDeviceId": logDeviceID, "parentId": parentID})
khenaidoob9203542018-09-17 22:56:37 -0400427
npujar1d86a522019-11-14 17:11:16 +0530428 if parentID == "" || logDeviceID == "" {
khenaidoo2c6a0992019-04-29 13:46:56 -0400429 return errors.New("device-in-invalid-state")
khenaidoo5e677ae2019-02-28 17:26:29 -0500430 }
431
npujar467fe752020-01-16 20:17:45 +0530432 if agent := ldMgr.getLogicalDeviceAgent(ctx, logDeviceID); agent != nil {
khenaidoofc1314d2019-03-14 09:34:21 -0400433 if err := agent.setupUNILogicalPorts(ctx, childDevice); err != nil {
khenaidoobcf205b2019-01-25 22:21:14 -0500434 return err
435 }
khenaidoob9203542018-09-17 22:56:37 -0400436 }
khenaidoo21d51152019-02-01 13:48:37 -0500437 return nil
khenaidoob9203542018-09-17 22:56:37 -0400438}
khenaidoo19d7b632018-10-30 10:49:50 -0400439
Kent Hagerman2b216042020-04-03 18:28:56 -0400440func (ldMgr *LogicalManager) deleteAllLogicalPorts(ctx context.Context, device *voltha.Device) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000441 logger.Debugw("deleteAllLogicalPorts", log.Fields{"deviceId": device.Id})
khenaidoo0a822f92019-05-08 15:15:57 -0400442
npujar1d86a522019-11-14 17:11:16 +0530443 var ldID *string
khenaidoo0a822f92019-05-08 15:15:57 -0400444 var err error
445 //Get the logical device Id for this device
npujar467fe752020-01-16 20:17:45 +0530446 if ldID, err = ldMgr.getLogicalDeviceID(ctx, device); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000447 logger.Warnw("no-logical-device-found", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo0a822f92019-05-08 15:15:57 -0400448 return err
449 }
npujar467fe752020-01-16 20:17:45 +0530450 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
Girish Gowdra408cd962020-03-11 14:31:31 -0700451 if err := agent.deleteAllLogicalPorts(ctx); err != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400452 return err
453 }
454 }
455 return nil
456}
Hardik Windlassc704def2020-02-26 18:23:19 +0000457
Kent Hagerman2b216042020-04-03 18:28:56 -0400458func (ldMgr *LogicalManager) deleteAllUNILogicalPorts(ctx context.Context, parentDevice *voltha.Device) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000459 logger.Debugw("delete-all-uni-logical-ports", log.Fields{"parent-device-id": parentDevice.Id})
Hardik Windlassc704def2020-02-26 18:23:19 +0000460
461 var ldID *string
462 var err error
463 //Get the logical device Id for this device
464 if ldID, err = ldMgr.getLogicalDeviceID(ctx, parentDevice); err != nil {
465 return err
466 }
467 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
468 if err := agent.deleteAllUNILogicalPorts(ctx, parentDevice); err != nil {
469 return err
470 }
471 }
472 return nil
473}
474
Kent Hagerman2b216042020-04-03 18:28:56 -0400475func (ldMgr *LogicalManager) updatePortState(ctx context.Context, deviceID string, portNo uint32, state voltha.OperStatus_Types) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000476 logger.Debugw("updatePortState", log.Fields{"deviceId": deviceID, "state": state, "portNo": portNo})
khenaidoo171b98e2019-10-31 11:48:15 -0400477
npujar1d86a522019-11-14 17:11:16 +0530478 var ldID *string
khenaidoo171b98e2019-10-31 11:48:15 -0400479 var err error
480 //Get the logical device Id for this device
npujar467fe752020-01-16 20:17:45 +0530481 if ldID, err = ldMgr.getLogicalDeviceIDFromDeviceID(ctx, deviceID); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000482 logger.Warnw("no-logical-device-found", log.Fields{"deviceId": deviceID, "error": err})
khenaidoo171b98e2019-10-31 11:48:15 -0400483 return err
484 }
npujar467fe752020-01-16 20:17:45 +0530485 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
486 if err := agent.updatePortState(ctx, deviceID, portNo, state); err != nil {
khenaidoo171b98e2019-10-31 11:48:15 -0400487 return err
488 }
489 }
490 return nil
491}
khenaidoo0a822f92019-05-08 15:15:57 -0400492
Kent Hagerman2b216042020-04-03 18:28:56 -0400493func (ldMgr *LogicalManager) updatePortsState(ctx context.Context, device *voltha.Device, state voltha.OperStatus_Types) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000494 logger.Debugw("updatePortsState", log.Fields{"deviceId": device.Id, "state": state, "current-data": device})
khenaidoo3ab34882019-05-02 21:33:30 -0400495
npujar1d86a522019-11-14 17:11:16 +0530496 var ldID *string
khenaidoo3ab34882019-05-02 21:33:30 -0400497 var err error
498 //Get the logical device Id for this device
npujar467fe752020-01-16 20:17:45 +0530499 if ldID, err = ldMgr.getLogicalDeviceID(ctx, device); err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000500 logger.Warnw("no-logical-device-found", log.Fields{"deviceId": device.Id, "error": err})
khenaidoo3ab34882019-05-02 21:33:30 -0400501 return err
502 }
npujar467fe752020-01-16 20:17:45 +0530503 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
504 if err := agent.updatePortsState(ctx, device, state); err != nil {
khenaidoo3ab34882019-05-02 21:33:30 -0400505 return err
506 }
507 }
508 return nil
509}
510
Kent Hagerman45a13e42020-04-13 12:23:50 -0400511// UpdateLogicalDeviceFlowTable updates logical device flow table
512func (ldMgr *LogicalManager) UpdateLogicalDeviceFlowTable(ctx context.Context, flow *openflow_13.FlowTableUpdate) (*empty.Empty, error) {
513 logger.Debugw("UpdateLogicalDeviceFlowTable", log.Fields{"logicalDeviceId": flow.Id})
514 agent := ldMgr.getLogicalDeviceAgent(ctx, flow.Id)
515 if agent == nil {
516 return nil, status.Errorf(codes.NotFound, "%s", flow.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400517 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400518 return &empty.Empty{}, agent.updateFlowTable(ctx, flow.FlowMod)
khenaidoo19d7b632018-10-30 10:49:50 -0400519}
520
Kent Hagerman45a13e42020-04-13 12:23:50 -0400521// UpdateLogicalDeviceMeterTable - This function sends meter mod request to logical device manager and waits for response
522func (ldMgr *LogicalManager) UpdateLogicalDeviceMeterTable(ctx context.Context, meter *openflow_13.MeterModUpdate) (*empty.Empty, error) {
523 logger.Debugw("UpdateLogicalDeviceMeterTable", log.Fields{"logicalDeviceId": meter.Id})
524 agent := ldMgr.getLogicalDeviceAgent(ctx, meter.Id)
525 if agent == nil {
526 return nil, status.Errorf(codes.NotFound, "%s", meter.Id)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400527 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400528 return &empty.Empty{}, agent.updateMeterTable(ctx, meter.MeterMod)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400529}
530
npujar1d86a522019-11-14 17:11:16 +0530531// ListLogicalDeviceMeters returns logical device meters
Kent Hagerman45a13e42020-04-13 12:23:50 -0400532func (ldMgr *LogicalManager) ListLogicalDeviceMeters(ctx context.Context, id *voltha.ID) (*openflow_13.Meters, error) {
533 logger.Debugw("ListLogicalDeviceMeters", log.Fields{"logicalDeviceId": id.Id})
534 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
535 if agent == nil {
536 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400537 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400538 return agent.ListLogicalDeviceMeters(ctx)
khenaidoo19d7b632018-10-30 10:49:50 -0400539}
540
Kent Hagerman45a13e42020-04-13 12:23:50 -0400541// UpdateLogicalDeviceFlowGroupTable updates logical device flow group table
542func (ldMgr *LogicalManager) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, flow *openflow_13.FlowGroupTableUpdate) (*empty.Empty, error) {
543 logger.Debugw("UpdateGroupTable", log.Fields{"logicalDeviceId": flow.Id})
544 agent := ldMgr.getLogicalDeviceAgent(ctx, flow.Id)
545 if agent == nil {
546 return nil, status.Errorf(codes.NotFound, "%s", flow.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400547 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400548 return &empty.Empty{}, agent.updateGroupTable(ctx, flow.GroupMod)
khenaidoo19d7b632018-10-30 10:49:50 -0400549}
550
Kent Hagerman45a13e42020-04-13 12:23:50 -0400551// EnableLogicalDevicePort enables logical device port
552func (ldMgr *LogicalManager) EnableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
553 logger.Debugw("EnableLogicalDevicePort", log.Fields{"logicalDeviceId": id})
554 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
555 if agent == nil {
556 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400557 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400558 return &empty.Empty{}, agent.enableLogicalPort(ctx, id.PortId)
559}
560
561// DisableLogicalDevicePort disables logical device port
562func (ldMgr *LogicalManager) DisableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
563 logger.Debugw("DisableLogicalDevicePort", log.Fields{"logicalDeviceId": id})
564 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
565 if agent == nil {
566 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
567 }
568 return &empty.Empty{}, agent.disableLogicalPort(ctx, id.PortId)
khenaidoo19d7b632018-10-30 10:49:50 -0400569}
khenaidoofdbad6e2018-11-06 22:26:38 -0500570
Kent Hagerman2b216042020-04-03 18:28:56 -0400571func (ldMgr *LogicalManager) packetIn(ctx context.Context, logicalDeviceID string, port uint32, transactionID string, packet []byte) error {
Girish Kumarf56a4682020-03-20 20:07:46 +0000572 logger.Debugw("packetIn", log.Fields{"logicalDeviceId": logicalDeviceID, "port": port})
npujar467fe752020-01-16 20:17:45 +0530573 if agent := ldMgr.getLogicalDeviceAgent(ctx, logicalDeviceID); agent != nil {
npujar1d86a522019-11-14 17:11:16 +0530574 agent.packetIn(port, transactionID, packet)
khenaidoofdbad6e2018-11-06 22:26:38 -0500575 } else {
Girish Kumarf56a4682020-03-20 20:07:46 +0000576 logger.Error("logical-device-not-exist", log.Fields{"logicalDeviceId": logicalDeviceID})
khenaidoofdbad6e2018-11-06 22:26:38 -0500577 }
578 return nil
579}
Kent Hagerman2b216042020-04-03 18:28:56 -0400580
Kent Hagerman45a13e42020-04-13 12:23:50 -0400581// StreamPacketsOut sends packets to adapter
582func (ldMgr *LogicalManager) StreamPacketsOut(packets voltha.VolthaService_StreamPacketsOutServer) error {
583 logger.Debugw("StreamPacketsOut-request", log.Fields{"packets": packets})
584loop:
585 for {
586 select {
587 case <-packets.Context().Done():
588 logger.Infow("StreamPacketsOut-context-done", log.Fields{"packets": packets, "error": packets.Context().Err()})
589 break loop
590 default:
591 }
592
593 packet, err := packets.Recv()
594
595 if err == io.EOF {
596 logger.Debugw("Received-EOF", log.Fields{"packets": packets})
597 break loop
598 }
599
600 if err != nil {
601 logger.Errorw("Failed to receive packet out", log.Fields{"error": err})
602 continue
603 }
604
605 if agent := ldMgr.getLogicalDeviceAgent(packets.Context(), packet.Id); agent != nil {
606 agent.packetOut(packets.Context(), packet.PacketOut)
607 } else {
608 logger.Errorf("No logical device agent present", log.Fields{"logicalDeviceID": packet.Id})
609 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400610 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400611
612 logger.Debugw("StreamPacketsOut-request-done", log.Fields{"packets": packets})
613 return nil
Kent Hagerman2b216042020-04-03 18:28:56 -0400614}