blob: 8a2a8a819d204423f44c6e4a3b7448836180c650 [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 "io"
Kent Hagermanfa9d6d42020-05-25 11:49:40 -040023 "strconv"
David Bainbridged1afd662020-03-26 18:27:41 -070024 "strings"
25 "sync"
26 "time"
27
Kent Hagerman433a31a2020-05-20 19:04:48 -040028 "github.com/golang/protobuf/ptypes/empty"
sbarbari17d7e222019-11-05 10:02:29 -050029 "github.com/opencord/voltha-go/db/model"
Kent Hagerman433a31a2020-05-20 19:04:48 -040030 "github.com/opencord/voltha-go/rw_core/core/device/event"
31 "github.com/opencord/voltha-go/rw_core/utils"
khenaidood948f772021-08-11 17:49:24 -040032 "github.com/opencord/voltha-lib-go/v7/pkg/log"
serkant.uluderyaad1e6832020-12-17 21:08:38 +030033 "github.com/opencord/voltha-lib-go/v7/pkg/probe"
khenaidood948f772021-08-11 17:49:24 -040034 "github.com/opencord/voltha-protos/v5/go/openflow_13"
35 "github.com/opencord/voltha-protos/v5/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
Mahir Gunyel03de0d32020-06-03 01:36:59 -070045 dbPath *model.Path
Kent Hagermanf5a67352020-04-30 15:15:26 -040046 ldProxy *model.Proxy
khenaidood948f772021-08-11 17:49:24 -040047 internalTimeout time.Duration
khenaidoo4c9e5592019-09-09 16:20:41 -040048 logicalDevicesLoadingLock sync.RWMutex
49 logicalDeviceLoadingInProgress map[string][]chan int
khenaidoob9203542018-09-17 22:56:37 -040050}
51
khenaidood948f772021-08-11 17:49:24 -040052func (ldMgr *LogicalManager) Start(ctx context.Context, serviceName string) {
khenaidoo7585a962021-06-10 16:15:38 -040053 logger.Info(ctx, "starting-logical-device-manager")
khenaidood948f772021-08-11 17:49:24 -040054 probe.UpdateStatusFromContext(ctx, serviceName, probe.ServiceStatusPreparing)
khenaidoo7585a962021-06-10 16:15:38 -040055
56 // Load all the logical devices from the dB
57 var logicalDevices []*voltha.LogicalDevice
58 if err := ldMgr.ldProxy.List(ctx, &logicalDevices); err != nil {
khenaidood948f772021-08-11 17:49:24 -040059 logger.Fatalw(ctx, "failed-to-list-logical-devices-from-cluster-proxy", log.Fields{"error": err, "service-name": serviceName})
khenaidoo7585a962021-06-10 16:15:38 -040060 }
61 for _, lDevice := range logicalDevices {
62 // Create an agent for each device
khenaidood948f772021-08-11 17:49:24 -040063 agent := newLogicalAgent(ctx, lDevice.Id, "", "", ldMgr, ldMgr.deviceMgr, ldMgr.dbPath, ldMgr.ldProxy, ldMgr.internalTimeout)
khenaidoo7585a962021-06-10 16:15:38 -040064 if err := agent.start(ctx, true, lDevice); err != nil {
65 logger.Warnw(ctx, "failure-starting-logical-agent", log.Fields{"logical-device-id": lDevice.Id})
66 } else {
67 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceID, agent)
68 }
69 }
70
khenaidood948f772021-08-11 17:49:24 -040071 probe.UpdateStatusFromContext(ctx, serviceName, probe.ServiceStatusRunning)
khenaidoo7585a962021-06-10 16:15:38 -040072 logger.Info(ctx, "logical-device-manager-started")
73}
74
Kent Hagerman2b216042020-04-03 18:28:56 -040075func (ldMgr *LogicalManager) addLogicalDeviceAgentToMap(agent *LogicalAgent) {
npujar1d86a522019-11-14 17:11:16 +053076 if _, exist := ldMgr.logicalDeviceAgents.Load(agent.logicalDeviceID); !exist {
77 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceID, agent)
khenaidoob9203542018-09-17 22:56:37 -040078 }
79}
80
khenaidoo8c3303d2019-02-13 14:59:39 -050081// getLogicalDeviceAgent returns the logical device agent. If the device is not in memory then the device will
82// be loaded from dB and a logical device agent created to managed it.
Kent Hagerman2b216042020-04-03 18:28:56 -040083func (ldMgr *LogicalManager) getLogicalDeviceAgent(ctx context.Context, logicalDeviceID string) *LogicalAgent {
Rohan Agrawal31f21802020-06-12 05:38:46 +000084 logger.Debugw(ctx, "get-logical-device-agent", log.Fields{"logical-device-id": logicalDeviceID})
npujar1d86a522019-11-14 17:11:16 +053085 agent, ok := ldMgr.logicalDeviceAgents.Load(logicalDeviceID)
86 if ok {
Kent Hagerman2b216042020-04-03 18:28:56 -040087 lda := agent.(*LogicalAgent)
khenaidoo93d5a3d2020-01-15 12:37:05 -050088 if lda.logicalDevice == nil {
89 // This can happen when an agent for the logical device has been created but the logical device
90 // itself is not ready for action as it is waiting for switch and port capabilities from the
91 // relevant adapter. In such a case prevent any request aimed at that logical device.
Himani Chawlab4c25912020-11-12 17:16:38 +053092 logger.Debugf(ctx, "logical-device-%s-is-not-ready-to-serve-requests", logicalDeviceID)
khenaidoo93d5a3d2020-01-15 12:37:05 -050093 return nil
94 }
95 return lda
npujar1d86a522019-11-14 17:11:16 +053096 }
97 // Try to load into memory - loading will also create the logical device agent
npujar467fe752020-01-16 20:17:45 +053098 if err := ldMgr.load(ctx, logicalDeviceID); err == nil {
npujar1d86a522019-11-14 17:11:16 +053099 if agent, ok = ldMgr.logicalDeviceAgents.Load(logicalDeviceID); ok {
Kent Hagerman2b216042020-04-03 18:28:56 -0400100 return agent.(*LogicalAgent)
khenaidoo8c3303d2019-02-13 14:59:39 -0500101 }
khenaidoob9203542018-09-17 22:56:37 -0400102 }
103 return nil
104}
105
Kent Hagerman2b216042020-04-03 18:28:56 -0400106func (ldMgr *LogicalManager) deleteLogicalDeviceAgent(logicalDeviceID string) {
Andrea Campanella832cff62021-11-05 17:05:18 +0100107 logger.Debugw(context.Background(), "delete-logical-device-agent", log.Fields{"logical-device-id": logicalDeviceID})
npujar1d86a522019-11-14 17:11:16 +0530108 ldMgr.logicalDeviceAgents.Delete(logicalDeviceID)
khenaidoo92e62c52018-10-03 14:02:54 -0400109}
110
khenaidoo8c3303d2019-02-13 14:59:39 -0500111// GetLogicalDevice provides a cloned most up to date logical device. If device is not in memory
112// it will be fetched from the dB
Kent Hagerman45a13e42020-04-13 12:23:50 -0400113func (ldMgr *LogicalManager) GetLogicalDevice(ctx context.Context, id *voltha.ID) (*voltha.LogicalDevice, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530114 ctx = utils.WithRPCMetadataContext(ctx, "GetLogicalDevice")
115 logger.Debugw(ctx, "get-logical-device", log.Fields{"logical-device-id": id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400116 if agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id); agent != nil {
Kent Hagermancba2f302020-07-28 13:37:36 -0400117 return agent.GetLogicalDeviceReadOnly(ctx)
khenaidoob9203542018-09-17 22:56:37 -0400118 }
119 return nil, status.Errorf(codes.NotFound, "%s", id)
120}
121
Kent Hagerman2b216042020-04-03 18:28:56 -0400122//ListLogicalDevices returns the list of all logical devices
Kent Hagerman45a13e42020-04-13 12:23:50 -0400123func (ldMgr *LogicalManager) ListLogicalDevices(ctx context.Context, _ *empty.Empty) (*voltha.LogicalDevices, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530124 ctx = utils.WithRPCMetadataContext(ctx, "ListLogicalDevices")
125 logger.Debug(ctx, "list-all-logical-devices")
Kent Hagerman4f355f52020-03-30 16:01:33 -0400126
127 var logicalDevices []*voltha.LogicalDevice
Esin Karamana4e4e002021-03-02 10:42:16 +0000128 ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
129 if ld, err := value.(*LogicalAgent).GetLogicalDeviceReadOnly(ctx); err == nil {
khenaidood948f772021-08-11 17:49:24 -0400130 if ld != nil {
131 logicalDevices = append(logicalDevices, ld)
132 }
Esin Karamana4e4e002021-03-02 10:42:16 +0000133 } else {
134 logger.Errorw(ctx, "unable-to-get-logical-device", log.Fields{"err": err})
135 }
136 return true
137 })
khenaidoo7585a962021-06-10 16:15:38 -0400138 logger.Debugw(ctx, "list-all-logical-devices", log.Fields{"num-logical-devices": len(logicalDevices)})
139
Kent Hagerman4f355f52020-03-30 16:01:33 -0400140 return &voltha.LogicalDevices{Items: logicalDevices}, nil
khenaidoob9203542018-09-17 22:56:37 -0400141}
142
Kent Hagerman2b216042020-04-03 18:28:56 -0400143func (ldMgr *LogicalManager) createLogicalDevice(ctx context.Context, device *voltha.Device) (*string, error) {
divyadesaicb8b59d2020-08-18 09:55:47 +0000144 logger.Debugw(ctx, "creating-logical-device", log.Fields{"device-id": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400145 // Sanity check
146 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400147 return nil, errors.New("device-not-root")
khenaidoob9203542018-09-17 22:56:37 -0400148 }
149
150 // Create a logical device agent - the logical device Id is based on the mac address of the device
151 // For now use the serial number - it may contain any combination of alphabetic characters and numbers,
152 // with length varying from eight characters to a maximum of 14 characters. Mac Address is part of oneof
153 // in the Device model. May need to be moved out.
Kent Hagerman2b216042020-04-03 18:28:56 -0400154 id := utils.CreateLogicalDeviceID()
David Bainbridged1afd662020-03-26 18:27:41 -0700155 sn := strings.Replace(device.MacAddress, ":", "", -1)
khenaidoo92e62c52018-10-03 14:02:54 -0400156 if id == "" {
divyadesaicb8b59d2020-08-18 09:55:47 +0000157 logger.Errorw(ctx, "mac-address-not-set", log.Fields{"device-id": device.Id, "serial-number": sn})
khenaidoo92e62c52018-10-03 14:02:54 -0400158 return nil, errors.New("mac-address-not-set")
159 }
David Bainbridged1afd662020-03-26 18:27:41 -0700160
divyadesaicb8b59d2020-08-18 09:55:47 +0000161 logger.Debugw(ctx, "logical-device-id", log.Fields{"logical-device-id": id})
khenaidoob9203542018-09-17 22:56:37 -0400162
khenaidood948f772021-08-11 17:49:24 -0400163 agent := newLogicalAgent(ctx, id, sn, device.Id, ldMgr, ldMgr.deviceMgr, ldMgr.dbPath, ldMgr.ldProxy, ldMgr.internalTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400164 ldMgr.addLogicalDeviceAgentToMap(agent)
khenaidooad06fd72019-10-28 12:26:05 -0400165
166 // Update the root device with the logical device Id reference
npujar467fe752020-01-16 20:17:45 +0530167 if err := ldMgr.deviceMgr.setParentID(ctx, device, id); err != nil {
divyadesaicb8b59d2020-08-18 09:55:47 +0000168 logger.Errorw(ctx, "failed-setting-parent-id", log.Fields{"logical-device-id": id, "device-id": device.Id})
khenaidooad06fd72019-10-28 12:26:05 -0400169 return nil, err
170 }
171
npujar1d86a522019-11-14 17:11:16 +0530172 go func() {
Kent Hagermanf5a67352020-04-30 15:15:26 -0400173 //TODO: either wait for the agent to be started before returning, or
174 // implement locks in the agent to ensure request are not processed before start() is complete
Himani Chawlab4c25912020-11-12 17:16:38 +0530175 ldCtx := utils.WithSpanAndRPCMetadataFromContext(ctx)
khenaidoo7585a962021-06-10 16:15:38 -0400176 err := agent.start(ldCtx, false, nil)
npujar1d86a522019-11-14 17:11:16 +0530177 if err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000178 logger.Errorw(ctx, "unable-to-create-the-logical-device", log.Fields{"error": err})
khenaidoo442e7c72020-03-10 16:13:48 -0400179 ldMgr.deleteLogicalDeviceAgent(id)
npujar1d86a522019-11-14 17:11:16 +0530180 }
181 }()
khenaidoob9203542018-09-17 22:56:37 -0400182
Rohan Agrawal31f21802020-06-12 05:38:46 +0000183 logger.Debug(ctx, "creating-logical-device-ends")
khenaidoob9203542018-09-17 22:56:37 -0400184 return &id, nil
185}
186
khenaidoo6d62c002019-05-15 21:57:03 -0400187// stopManagingLogicalDeviceWithDeviceId stops the management of the logical device. This implies removal of any
188// reference of this logical device in cache. The device Id is passed as param because the logical device may already
189// have been removed from the model. This function returns the logical device Id if found
Kent Hagerman2b216042020-04-03 18:28:56 -0400190func (ldMgr *LogicalManager) stopManagingLogicalDeviceWithDeviceID(ctx context.Context, id string) string {
divyadesaicb8b59d2020-08-18 09:55:47 +0000191 logger.Infow(ctx, "stop-managing-logical-device", log.Fields{"device-id": id})
khenaidoo6d62c002019-05-15 21:57:03 -0400192 // Go over the list of logical device agents to find the one which has rootDeviceId as id
npujar1d86a522019-11-14 17:11:16 +0530193 var ldID = ""
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400194 ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
Kent Hagerman2b216042020-04-03 18:28:56 -0400195 ldAgent := value.(*LogicalAgent)
npujar1d86a522019-11-14 17:11:16 +0530196 if ldAgent.rootDeviceID == id {
divyadesaicb8b59d2020-08-18 09:55:47 +0000197 logger.Infow(ctx, "stopping-logical-device-agent", log.Fields{"logical-device-id": key})
npujar467fe752020-01-16 20:17:45 +0530198 if err := ldAgent.stop(ctx); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000199 logger.Errorw(ctx, "failed-to-stop-LDAgent", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530200 return false
201 }
npujar1d86a522019-11-14 17:11:16 +0530202 ldID = key.(string)
203 ldMgr.logicalDeviceAgents.Delete(ldID)
khenaidoo6d62c002019-05-15 21:57:03 -0400204 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400205 return true
206 })
npujar1d86a522019-11-14 17:11:16 +0530207 return ldID
khenaidoo6d62c002019-05-15 21:57:03 -0400208}
209
210//getLogicalDeviceFromModel retrieves the logical device data from the model.
Kent Hagerman2b216042020-04-03 18:28:56 -0400211func (ldMgr *LogicalManager) getLogicalDeviceFromModel(ctx context.Context, lDeviceID string) (*voltha.LogicalDevice, error) {
Kent Hagerman4f355f52020-03-30 16:01:33 -0400212 logicalDevice := &voltha.LogicalDevice{}
Kent Hagermanf5a67352020-04-30 15:15:26 -0400213 if have, err := ldMgr.ldProxy.Get(ctx, lDeviceID, logicalDevice); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000214 logger.Errorw(ctx, "failed-to-get-logical-devices-from-cluster-proxy", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530215 return nil, err
Kent Hagerman4f355f52020-03-30 16:01:33 -0400216 } else if !have {
217 return nil, status.Error(codes.NotFound, lDeviceID)
Thomas Lee Se5a44012019-11-07 20:32:24 +0530218 }
Kent Hagerman4f355f52020-03-30 16:01:33 -0400219
220 return logicalDevice, nil
khenaidoo6d62c002019-05-15 21:57:03 -0400221}
222
khenaidoo297cd252019-02-07 22:10:23 -0500223// load loads a logical device manager in memory
Kent Hagerman2b216042020-04-03 18:28:56 -0400224func (ldMgr *LogicalManager) load(ctx context.Context, lDeviceID string) error {
npujar1d86a522019-11-14 17:11:16 +0530225 if lDeviceID == "" {
khenaidoo4c9e5592019-09-09 16:20:41 -0400226 return nil
khenaidoo297cd252019-02-07 22:10:23 -0500227 }
khenaidoo4c9e5592019-09-09 16:20:41 -0400228 // Add a lock to prevent two concurrent calls from loading the same device twice
229 ldMgr.logicalDevicesLoadingLock.Lock()
npujar1d86a522019-11-14 17:11:16 +0530230 if _, exist := ldMgr.logicalDeviceLoadingInProgress[lDeviceID]; !exist {
231 if ldAgent, _ := ldMgr.logicalDeviceAgents.Load(lDeviceID); ldAgent == nil {
232 ldMgr.logicalDeviceLoadingInProgress[lDeviceID] = []chan int{make(chan int, 1)}
khenaidoo4c9e5592019-09-09 16:20:41 -0400233 ldMgr.logicalDevicesLoadingLock.Unlock()
npujar467fe752020-01-16 20:17:45 +0530234 if _, err := ldMgr.getLogicalDeviceFromModel(ctx, lDeviceID); err == nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000235 logger.Debugw(ctx, "loading-logical-device", log.Fields{"lDeviceId": lDeviceID})
khenaidood948f772021-08-11 17:49:24 -0400236 agent := newLogicalAgent(ctx, lDeviceID, "", "", ldMgr, ldMgr.deviceMgr, ldMgr.dbPath, ldMgr.ldProxy, ldMgr.internalTimeout)
khenaidoo7585a962021-06-10 16:15:38 -0400237 if err := agent.start(ctx, true, nil); err != nil {
khenaidoo442e7c72020-03-10 16:13:48 -0400238 return err
khenaidoo4c9e5592019-09-09 16:20:41 -0400239 }
khenaidoo442e7c72020-03-10 16:13:48 -0400240 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceID, agent)
khenaidoo4c9e5592019-09-09 16:20:41 -0400241 } else {
Himani Chawlab4c25912020-11-12 17:16:38 +0530242 logger.Debugw(ctx, "logical-device-not-in-model", log.Fields{"logical-device-id": lDeviceID})
khenaidoo4c9e5592019-09-09 16:20:41 -0400243 }
244 // announce completion of task to any number of waiting channels
245 ldMgr.logicalDevicesLoadingLock.Lock()
npujar1d86a522019-11-14 17:11:16 +0530246 if v, ok := ldMgr.logicalDeviceLoadingInProgress[lDeviceID]; ok {
khenaidoo4c9e5592019-09-09 16:20:41 -0400247 for _, ch := range v {
248 close(ch)
249 }
npujar1d86a522019-11-14 17:11:16 +0530250 delete(ldMgr.logicalDeviceLoadingInProgress, lDeviceID)
khenaidoo4c9e5592019-09-09 16:20:41 -0400251 }
252 ldMgr.logicalDevicesLoadingLock.Unlock()
253 } else {
254 ldMgr.logicalDevicesLoadingLock.Unlock()
255 }
256 } else {
257 ch := make(chan int, 1)
npujar1d86a522019-11-14 17:11:16 +0530258 ldMgr.logicalDeviceLoadingInProgress[lDeviceID] = append(ldMgr.logicalDeviceLoadingInProgress[lDeviceID], ch)
khenaidoo4c9e5592019-09-09 16:20:41 -0400259 ldMgr.logicalDevicesLoadingLock.Unlock()
260 // Wait for the channel to be closed, implying the process loading this device is done.
261 <-ch
262 }
npujar1d86a522019-11-14 17:11:16 +0530263 if _, exist := ldMgr.logicalDeviceAgents.Load(lDeviceID); exist {
khenaidoo4c9e5592019-09-09 16:20:41 -0400264 return nil
265 }
npujar1d86a522019-11-14 17:11:16 +0530266 return status.Errorf(codes.Aborted, "Error loading logical device %s", lDeviceID)
khenaidoo297cd252019-02-07 22:10:23 -0500267}
268
Kent Hagerman2b216042020-04-03 18:28:56 -0400269func (ldMgr *LogicalManager) deleteLogicalDevice(ctx context.Context, device *voltha.Device) error {
Andrea Campanella77dde842021-05-27 15:31:54 +0200270 logger.Infow(ctx, "deleting-logical-device", log.Fields{"device-id": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400271 // Sanity check
272 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400273 return errors.New("device-not-root")
khenaidoo92e62c52018-10-03 14:02:54 -0400274 }
npujar1d86a522019-11-14 17:11:16 +0530275 logDeviceID := device.ParentId
Andrea Campanella832cff62021-11-05 17:05:18 +0100276 if err := ldMgr.deleteAllLogicalMeters(ctx, logDeviceID); err != nil {
277 // Just log the error. The logical device or port may already have been deleted before this callback is invoked.
278 logger.Warnw(ctx, "delete-logical-meters-error", log.Fields{"device-id": logDeviceID, "error": err})
279 }
npujar467fe752020-01-16 20:17:45 +0530280 if agent := ldMgr.getLogicalDeviceAgent(ctx, logDeviceID); agent != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400281 // Stop the logical device agent
Thomas Lee Se5a44012019-11-07 20:32:24 +0530282 if err := agent.stop(ctx); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000283 logger.Errorw(ctx, "failed-to-stop-agent", log.Fields{"error": err})
Thomas Lee Se5a44012019-11-07 20:32:24 +0530284 return err
285 }
khenaidoo92e62c52018-10-03 14:02:54 -0400286 //Remove the logical device agent from the Map
npujar1d86a522019-11-14 17:11:16 +0530287 ldMgr.deleteLogicalDeviceAgent(logDeviceID)
Andrea Campanella77dde842021-05-27 15:31:54 +0200288 ldMgr.SendDeviceDeletionEvent(ctx, logDeviceID)
Andrea Campanella832cff62021-11-05 17:05:18 +0100289 } else {
290 logger.Warnw(ctx, "no-logical-device-agent-on-deletion", log.Fields{"device-id": logDeviceID})
khenaidoo92e62c52018-10-03 14:02:54 -0400291 }
Andrea Campanella77dde842021-05-27 15:31:54 +0200292 logger.Debugw(ctx, "deleting-logical-device-ends", log.Fields{"device-id": device.Id})
khenaidoo92e62c52018-10-03 14:02:54 -0400293 return nil
294}
295
Kent Hagerman2b216042020-04-03 18:28:56 -0400296func (ldMgr *LogicalManager) getLogicalDeviceID(ctx context.Context, device *voltha.Device) (*string, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400297 // Device can either be a parent or a child device
298 if device.Root {
299 // Parent device. The ID of a parent device is the logical device ID
300 return &device.ParentId, nil
301 }
302 // Device is child device
303 // retrieve parent device using child device ID
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400304 // TODO: return (string, have) instead of *string
305 // also: If not root device, just return device.parentID instead of loading the parent device.
npujar467fe752020-01-16 20:17:45 +0530306 if parentDevice := ldMgr.deviceMgr.getParentDevice(ctx, device); parentDevice != nil {
khenaidoo92e62c52018-10-03 14:02:54 -0400307 return &parentDevice.ParentId, nil
308 }
309 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
310}
311
Kent Hagerman2b216042020-04-03 18:28:56 -0400312func (ldMgr *LogicalManager) getLogicalDeviceIDFromDeviceID(ctx context.Context, deviceID string) (*string, error) {
khenaidoo3ab34882019-05-02 21:33:30 -0400313 // Get the device
314 var device *voltha.Device
315 var err error
Kent Hagermancba2f302020-07-28 13:37:36 -0400316 if device, err = ldMgr.deviceMgr.getDeviceReadOnly(ctx, deviceID); err != nil {
khenaidoo3ab34882019-05-02 21:33:30 -0400317 return nil, err
318 }
npujar467fe752020-01-16 20:17:45 +0530319 return ldMgr.getLogicalDeviceID(ctx, device)
khenaidoo3ab34882019-05-02 21:33:30 -0400320}
321
npujar1d86a522019-11-14 17:11:16 +0530322// ListLogicalDeviceFlows returns the flows of logical device
Kent Hagerman45a13e42020-04-13 12:23:50 -0400323func (ldMgr *LogicalManager) ListLogicalDeviceFlows(ctx context.Context, id *voltha.ID) (*openflow_13.Flows, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530324 ctx = utils.WithRPCMetadataContext(ctx, "ListLogicalDeviceFlows")
325 logger.Debugw(ctx, "list-logical-device-flows", log.Fields{"logical-device-id": id.Id})
Kent Hagerman433a31a2020-05-20 19:04:48 -0400326 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
327 if agent == nil {
328 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoodd237172019-05-27 16:37:17 -0400329 }
Kent Hagerman433a31a2020-05-20 19:04:48 -0400330
331 flows := agent.listLogicalDeviceFlows()
332 ctr, ret := 0, make([]*openflow_13.OfpFlowStats, len(flows))
333 for _, flow := range flows {
334 ret[ctr] = flow
335 ctr++
336 }
khenaidoo7585a962021-06-10 16:15:38 -0400337 logger.Debugw(ctx, "list-logical-device-flows", log.Fields{"logical-device-id": id.Id, "num-flows": len(flows)})
Kent Hagerman433a31a2020-05-20 19:04:48 -0400338 return &openflow_13.Flows{Items: ret}, nil
khenaidoodd237172019-05-27 16:37:17 -0400339}
340
npujar1d86a522019-11-14 17:11:16 +0530341// ListLogicalDeviceFlowGroups returns logical device flow groups
Kent Hagerman45a13e42020-04-13 12:23:50 -0400342func (ldMgr *LogicalManager) ListLogicalDeviceFlowGroups(ctx context.Context, id *voltha.ID) (*openflow_13.FlowGroups, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530343 ctx = utils.WithRPCMetadataContext(ctx, "ListLogicalDeviceFlowGroups")
344 logger.Debugw(ctx, "list-logical-device-flow-groups", log.Fields{"logical-device-id": id.Id})
Kent Hagerman433a31a2020-05-20 19:04:48 -0400345 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
346 if agent == nil {
347 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoodd237172019-05-27 16:37:17 -0400348 }
Kent Hagerman433a31a2020-05-20 19:04:48 -0400349
350 groups := agent.listLogicalDeviceGroups()
351 ctr, ret := 0, make([]*openflow_13.OfpGroupEntry, len(groups))
352 for _, group := range groups {
353 ret[ctr] = group
354 ctr++
355 }
khenaidoo7585a962021-06-10 16:15:38 -0400356 logger.Debugw(ctx, "list-logical-device-flow-groups", log.Fields{"logical-device-id": id.Id, "num-groups": len(groups)})
Kent Hagerman433a31a2020-05-20 19:04:48 -0400357 return &openflow_13.FlowGroups{Items: ret}, nil
khenaidoodd237172019-05-27 16:37:17 -0400358}
359
npujar1d86a522019-11-14 17:11:16 +0530360// ListLogicalDevicePorts returns logical device ports
Kent Hagerman45a13e42020-04-13 12:23:50 -0400361func (ldMgr *LogicalManager) ListLogicalDevicePorts(ctx context.Context, id *voltha.ID) (*voltha.LogicalPorts, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530362 ctx = utils.WithRPCMetadataContext(ctx, "ListLogicalDevicePorts")
363 logger.Debugw(ctx, "list-logical-device-ports", log.Fields{"logical-device-id": id.Id})
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400364 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
365 if agent == nil {
366 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400367 }
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400368
Rohan Agrawal31f21802020-06-12 05:38:46 +0000369 ports := agent.listLogicalDevicePorts(ctx)
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400370 ctr, ret := 0, make([]*voltha.LogicalPort, len(ports))
371 for _, port := range ports {
372 ret[ctr] = port
373 ctr++
374 }
khenaidoo7585a962021-06-10 16:15:38 -0400375 logger.Debugw(ctx, "list-logical-device-ports", log.Fields{"logical-device-id": id.Id, "num-ports": len(ports)})
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400376 return &voltha.LogicalPorts{Items: ret}, nil
khenaidoo19d7b632018-10-30 10:49:50 -0400377}
378
Kent Hagerman45a13e42020-04-13 12:23:50 -0400379// GetLogicalDevicePort returns logical device port details
380func (ldMgr *LogicalManager) GetLogicalDevicePort(ctx context.Context, lPortID *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530381 ctx = utils.WithRPCMetadataContext(ctx, "GetLogicalDevicePort")
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400382 // Get the logical device where this port is attached
383 agent := ldMgr.getLogicalDeviceAgent(ctx, lPortID.Id)
384 if agent == nil {
385 return nil, status.Errorf(codes.NotFound, "%s", lPortID.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400386 }
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400387
Rohan Agrawal31f21802020-06-12 05:38:46 +0000388 for _, port := range agent.listLogicalDevicePorts(ctx) {
npujar1d86a522019-11-14 17:11:16 +0530389 if port.Id == lPortID.PortId {
khenaidoo19d7b632018-10-30 10:49:50 -0400390 return port, nil
391 }
392 }
npujar1d86a522019-11-14 17:11:16 +0530393 return nil, status.Errorf(codes.NotFound, "%s-%s", lPortID.Id, lPortID.PortId)
khenaidoo19d7b632018-10-30 10:49:50 -0400394}
395
khenaidoo2c6a0992019-04-29 13:46:56 -0400396// updateLogicalPort sets up a logical port on the logical device based on the device port
397// information, if needed
Kent Hagerman2a07b862020-06-19 15:23:07 -0400398func (ldMgr *LogicalManager) updateLogicalPort(ctx context.Context, device *voltha.Device, devicePorts map[uint32]*voltha.Port, port *voltha.Port) error {
npujar467fe752020-01-16 20:17:45 +0530399 ldID, err := ldMgr.getLogicalDeviceID(ctx, device)
npujar1d86a522019-11-14 17:11:16 +0530400 if err != nil || *ldID == "" {
khenaidoo2c6a0992019-04-29 13:46:56 -0400401 // This is not an error as the logical device may not have been created at this time. In such a case,
402 // the ports will be created when the logical device is ready.
403 return nil
khenaidoo2c6a0992019-04-29 13:46:56 -0400404 }
npujar467fe752020-01-16 20:17:45 +0530405 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
Kent Hagerman2a07b862020-06-19 15:23:07 -0400406 if err := agent.updateLogicalPort(ctx, device, devicePorts, port); err != nil {
npujar1d86a522019-11-14 17:11:16 +0530407 return err
khenaidoofc1314d2019-03-14 09:34:21 -0400408 }
409 }
410 return nil
411}
412
khenaidoo0a822f92019-05-08 15:15:57 -0400413// deleteLogicalPort removes the logical port associated with a child device
Kent Hagerman2b216042020-04-03 18:28:56 -0400414func (ldMgr *LogicalManager) deleteLogicalPorts(ctx context.Context, deviceID string) error {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000415 logger.Debugw(ctx, "deleting-logical-ports", log.Fields{"device-id": deviceID})
khenaidoo0a822f92019-05-08 15:15:57 -0400416 // Get logical port
npujar467fe752020-01-16 20:17:45 +0530417 ldID, err := ldMgr.getLogicalDeviceIDFromDeviceID(ctx, deviceID)
npujar1d86a522019-11-14 17:11:16 +0530418 if err != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400419 return err
npujar1d86a522019-11-14 17:11:16 +0530420 }
npujar467fe752020-01-16 20:17:45 +0530421 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
422 if err = agent.deleteLogicalPorts(ctx, deviceID); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000423 logger.Warnw(ctx, "delete-logical-ports-failed", log.Fields{"logical-device-id": *ldID})
npujar1d86a522019-11-14 17:11:16 +0530424 return err
khenaidoo0a822f92019-05-08 15:15:57 -0400425 }
426 }
Andrea Campanella77dde842021-05-27 15:31:54 +0200427 logger.Debugw(ctx, "deleting-logical-ports-ends", log.Fields{"device-id": deviceID})
khenaidoo0a822f92019-05-08 15:15:57 -0400428 return nil
429}
430
serkant.uluderyaad1e6832020-12-17 21:08:38 +0300431// deleteAllLogicalMeters removes the logical meters associated with a child device
432func (ldMgr *LogicalManager) deleteAllLogicalMeters(ctx context.Context, deviceID string) error {
433 logger.Debugw(ctx, "delete-logical-meters", log.Fields{"device-id": deviceID})
434 // Get logical port
435 ldID, err := ldMgr.getLogicalDeviceIDFromDeviceID(ctx, deviceID)
436 if err != nil {
437 return err
438 }
439 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
440 for meterID := range agent.meterLoader.ListIDs() {
441 if meterHandle, have := agent.meterLoader.Lock(meterID); have {
442 // Update the store and cache
443 if err := meterHandle.Delete(ctx); err != nil {
444 meterHandle.Unlock()
445 logger.Errorw(ctx, "unable-to-delete-meter", log.Fields{"logical-device-id": ldID, "meterID": meterID})
446 continue
447 }
448 meterHandle.Unlock()
449 }
450 }
451 }
452 return nil
453}
454
Kent Hagerman2a07b862020-06-19 15:23:07 -0400455func (ldMgr *LogicalManager) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device, childDevicePorts map[uint32]*voltha.Port) error {
Himani Chawlab4c25912020-11-12 17:16:38 +0530456 logger.Debugw(ctx, "setup-uni-logical-ports", log.Fields{"child-device-id": childDevice.Id, "parent-device-id": childDevice.ParentId, "current-data": childDevice})
khenaidoob9203542018-09-17 22:56:37 -0400457 // Sanity check
458 if childDevice.Root {
459 return errors.New("Device-root")
460 }
461
462 // Get the logical device id parent device
npujar1d86a522019-11-14 17:11:16 +0530463 parentID := childDevice.ParentId
npujar467fe752020-01-16 20:17:45 +0530464 logDeviceID := ldMgr.deviceMgr.GetParentDeviceID(ctx, parentID)
khenaidoob9203542018-09-17 22:56:37 -0400465
Himani Chawlab4c25912020-11-12 17:16:38 +0530466 logger.Debugw(ctx, "setup-uni-logical-ports", log.Fields{"logical-device-id": logDeviceID, "parentId": parentID})
khenaidoob9203542018-09-17 22:56:37 -0400467
npujar1d86a522019-11-14 17:11:16 +0530468 if parentID == "" || logDeviceID == "" {
khenaidoo2c6a0992019-04-29 13:46:56 -0400469 return errors.New("device-in-invalid-state")
khenaidoo5e677ae2019-02-28 17:26:29 -0500470 }
471
npujar467fe752020-01-16 20:17:45 +0530472 if agent := ldMgr.getLogicalDeviceAgent(ctx, logDeviceID); agent != nil {
Kent Hagerman2a07b862020-06-19 15:23:07 -0400473 if err := agent.setupUNILogicalPorts(ctx, childDevice, childDevicePorts); err != nil {
khenaidoobcf205b2019-01-25 22:21:14 -0500474 return err
475 }
khenaidoob9203542018-09-17 22:56:37 -0400476 }
khenaidoo21d51152019-02-01 13:48:37 -0500477 return nil
khenaidoob9203542018-09-17 22:56:37 -0400478}
khenaidoo19d7b632018-10-30 10:49:50 -0400479
Kent Hagerman2b216042020-04-03 18:28:56 -0400480func (ldMgr *LogicalManager) deleteAllLogicalPorts(ctx context.Context, device *voltha.Device) error {
Himani Chawlab4c25912020-11-12 17:16:38 +0530481 logger.Debugw(ctx, "delete-all-logical-ports", log.Fields{"device-id": device.Id})
khenaidoo0a822f92019-05-08 15:15:57 -0400482
npujar1d86a522019-11-14 17:11:16 +0530483 var ldID *string
khenaidoo0a822f92019-05-08 15:15:57 -0400484 var err error
485 //Get the logical device Id for this device
npujar467fe752020-01-16 20:17:45 +0530486 if ldID, err = ldMgr.getLogicalDeviceID(ctx, device); err != nil {
divyadesaicb8b59d2020-08-18 09:55:47 +0000487 logger.Warnw(ctx, "no-logical-device-found", log.Fields{"device-id": device.Id, "error": err})
khenaidoo0a822f92019-05-08 15:15:57 -0400488 return err
489 }
npujar467fe752020-01-16 20:17:45 +0530490 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
Girish Gowdra408cd962020-03-11 14:31:31 -0700491 if err := agent.deleteAllLogicalPorts(ctx); err != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400492 return err
493 }
494 }
495 return nil
496}
Hardik Windlassc704def2020-02-26 18:23:19 +0000497
Kent Hagerman2b216042020-04-03 18:28:56 -0400498func (ldMgr *LogicalManager) updatePortState(ctx context.Context, deviceID string, portNo uint32, state voltha.OperStatus_Types) error {
Himani Chawlab4c25912020-11-12 17:16:38 +0530499 logger.Debugw(ctx, "update-Port-state", log.Fields{"device-id": deviceID, "state": state, "port-no": portNo})
khenaidoo171b98e2019-10-31 11:48:15 -0400500
npujar1d86a522019-11-14 17:11:16 +0530501 var ldID *string
khenaidoo171b98e2019-10-31 11:48:15 -0400502 var err error
503 //Get the logical device Id for this device
npujar467fe752020-01-16 20:17:45 +0530504 if ldID, err = ldMgr.getLogicalDeviceIDFromDeviceID(ctx, deviceID); err != nil {
divyadesaicb8b59d2020-08-18 09:55:47 +0000505 logger.Warnw(ctx, "no-logical-device-found", log.Fields{"device-id": deviceID, "error": err})
khenaidoo171b98e2019-10-31 11:48:15 -0400506 return err
507 }
npujar467fe752020-01-16 20:17:45 +0530508 if agent := ldMgr.getLogicalDeviceAgent(ctx, *ldID); agent != nil {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400509 if err := agent.updatePortState(ctx, portNo, state); err != nil {
khenaidoo171b98e2019-10-31 11:48:15 -0400510 return err
511 }
512 }
513 return nil
514}
khenaidoo0a822f92019-05-08 15:15:57 -0400515
Kent Hagerman45a13e42020-04-13 12:23:50 -0400516// UpdateLogicalDeviceFlowTable updates logical device flow table
517func (ldMgr *LogicalManager) UpdateLogicalDeviceFlowTable(ctx context.Context, flow *openflow_13.FlowTableUpdate) (*empty.Empty, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530518 ctx = utils.WithRPCMetadataContext(ctx, "UpdateLogicalDeviceFlowTable")
519 logger.Debugw(ctx, "update-logical-device-flow-table", log.Fields{"logical-device-id": flow.Id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400520 agent := ldMgr.getLogicalDeviceAgent(ctx, flow.Id)
521 if agent == nil {
522 return nil, status.Errorf(codes.NotFound, "%s", flow.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400523 }
Maninderf421da62020-12-04 11:44:58 +0530524 return &empty.Empty{}, agent.updateFlowTable(ctx, flow)
khenaidoo19d7b632018-10-30 10:49:50 -0400525}
526
Kent Hagerman45a13e42020-04-13 12:23:50 -0400527// UpdateLogicalDeviceMeterTable - This function sends meter mod request to logical device manager and waits for response
528func (ldMgr *LogicalManager) UpdateLogicalDeviceMeterTable(ctx context.Context, meter *openflow_13.MeterModUpdate) (*empty.Empty, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530529 ctx = utils.WithRPCMetadataContext(ctx, "UpdateLogicalDeviceMeterTable")
530 logger.Debugw(ctx, "update-logical-device-meter-table", log.Fields{"logical-device-id": meter.Id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400531 agent := ldMgr.getLogicalDeviceAgent(ctx, meter.Id)
532 if agent == nil {
533 return nil, status.Errorf(codes.NotFound, "%s", meter.Id)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400534 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400535 return &empty.Empty{}, agent.updateMeterTable(ctx, meter.MeterMod)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400536}
537
npujar1d86a522019-11-14 17:11:16 +0530538// ListLogicalDeviceMeters returns logical device meters
Kent Hagerman45a13e42020-04-13 12:23:50 -0400539func (ldMgr *LogicalManager) ListLogicalDeviceMeters(ctx context.Context, id *voltha.ID) (*openflow_13.Meters, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530540 ctx = utils.WithRPCMetadataContext(ctx, "ListLogicalDeviceMeters")
541 logger.Debugw(ctx, "list-logical-device-meters", log.Fields{"logical-device-id": id.Id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400542 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
543 if agent == nil {
544 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400545 }
khenaidoo1a0d6222021-06-30 16:48:44 -0400546 meters := agent.listLogicalDeviceMeters(ctx)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400547 ctr, ret := 0, make([]*openflow_13.OfpMeterEntry, len(meters))
548 for _, meter := range meters {
549 ret[ctr] = meter
550 ctr++
551 }
552 return &openflow_13.Meters{Items: ret}, nil
khenaidoo19d7b632018-10-30 10:49:50 -0400553}
554
Kent Hagerman45a13e42020-04-13 12:23:50 -0400555// UpdateLogicalDeviceFlowGroupTable updates logical device flow group table
556func (ldMgr *LogicalManager) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, flow *openflow_13.FlowGroupTableUpdate) (*empty.Empty, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530557 ctx = utils.WithRPCMetadataContext(ctx, "UpdateLogicalDeviceFlowGroupTable")
558 logger.Debugw(ctx, "update-group-table", log.Fields{"logical-device-id": flow.Id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400559 agent := ldMgr.getLogicalDeviceAgent(ctx, flow.Id)
560 if agent == nil {
561 return nil, status.Errorf(codes.NotFound, "%s", flow.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400562 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400563 return &empty.Empty{}, agent.updateGroupTable(ctx, flow.GroupMod)
khenaidoo19d7b632018-10-30 10:49:50 -0400564}
565
Kent Hagerman45a13e42020-04-13 12:23:50 -0400566// EnableLogicalDevicePort enables logical device port
567func (ldMgr *LogicalManager) EnableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530568 ctx = utils.WithRPCMetadataContext(ctx, "EnableLogicalDevicePort")
569 logger.Debugw(ctx, "enable-logical-device-port", log.Fields{"logical-device-id": id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400570 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
571 if agent == nil {
572 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
khenaidoo19d7b632018-10-30 10:49:50 -0400573 }
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400574 portNo, err := strconv.ParseUint(id.PortId, 10, 32)
575 if err != nil {
576 return nil, status.Errorf(codes.InvalidArgument, "failed to parse %s as a number", id.PortId)
577 }
578 return &empty.Empty{}, agent.enableLogicalPort(ctx, uint32(portNo))
Kent Hagerman45a13e42020-04-13 12:23:50 -0400579}
580
581// DisableLogicalDevicePort disables logical device port
582func (ldMgr *LogicalManager) DisableLogicalDevicePort(ctx context.Context, id *voltha.LogicalPortId) (*empty.Empty, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530583 ctx = utils.WithRPCMetadataContext(ctx, "DisableLogicalDevicePort")
584 logger.Debugw(ctx, "disable-logical-device-port", log.Fields{"logical-device-id": id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400585 agent := ldMgr.getLogicalDeviceAgent(ctx, id.Id)
586 if agent == nil {
587 return nil, status.Errorf(codes.NotFound, "%s", id.Id)
588 }
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400589 portNo, err := strconv.ParseUint(id.PortId, 10, 32)
590 if err != nil {
591 return nil, status.Errorf(codes.InvalidArgument, "failed to parse %s as a number", id.PortId)
592 }
593 return &empty.Empty{}, agent.disableLogicalPort(ctx, uint32(portNo))
khenaidoo19d7b632018-10-30 10:49:50 -0400594}
khenaidoofdbad6e2018-11-06 22:26:38 -0500595
khenaidood948f772021-08-11 17:49:24 -0400596func (ldMgr *LogicalManager) packetIn(ctx context.Context, logicalDeviceID string, port uint32, packet []byte) error {
Himani Chawlab4c25912020-11-12 17:16:38 +0530597 logger.Debugw(ctx, "packet-in", log.Fields{"logical-device-id": logicalDeviceID, "port": port})
npujar467fe752020-01-16 20:17:45 +0530598 if agent := ldMgr.getLogicalDeviceAgent(ctx, logicalDeviceID); agent != nil {
khenaidood948f772021-08-11 17:49:24 -0400599 agent.packetIn(ctx, port, packet)
khenaidoofdbad6e2018-11-06 22:26:38 -0500600 } else {
divyadesaicb8b59d2020-08-18 09:55:47 +0000601 logger.Error(ctx, "logical-device-not-exist", log.Fields{"logical-device-id": logicalDeviceID})
khenaidoofdbad6e2018-11-06 22:26:38 -0500602 }
603 return nil
604}
Kent Hagerman2b216042020-04-03 18:28:56 -0400605
Kent Hagerman45a13e42020-04-13 12:23:50 -0400606// StreamPacketsOut sends packets to adapter
607func (ldMgr *LogicalManager) StreamPacketsOut(packets voltha.VolthaService_StreamPacketsOutServer) error {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000608 ctx := context.Background()
Himani Chawlab4c25912020-11-12 17:16:38 +0530609 logger.Debugw(ctx, "stream-packets-out-request", log.Fields{"packets": packets})
610
Kent Hagerman45a13e42020-04-13 12:23:50 -0400611loop:
612 for {
613 select {
614 case <-packets.Context().Done():
Himani Chawlab4c25912020-11-12 17:16:38 +0530615 logger.Infow(ctx, "stream-packets-out-context-done", log.Fields{"packets": packets, "error": packets.Context().Err()})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400616 break loop
617 default:
618 }
619
620 packet, err := packets.Recv()
621
Himani Chawlab4c25912020-11-12 17:16:38 +0530622 pktCtx := utils.WithRPCMetadataContext(packets.Context(), "StreamPacketsOut")
623
Kent Hagerman45a13e42020-04-13 12:23:50 -0400624 if err == io.EOF {
Himani Chawlab4c25912020-11-12 17:16:38 +0530625 logger.Debugw(ctx, "received-eof", log.Fields{"packets": packets})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400626 break loop
627 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400628 if err != nil {
Himani Chawlab4c25912020-11-12 17:16:38 +0530629 logger.Errorw(ctx, "failed-to-receive-packet-out", log.Fields{"error": err})
Andrea Campanellaff2d73a2021-03-04 14:47:17 +0100630 // we do not have the resource Id here due to error in the packet, setting to empty
Himani Chawla606a4f02021-03-23 19:45:58 +0530631 ldMgr.SendRPCEvent(pktCtx, "", err.Error(), nil,
632 "RPC_ERROR_RAISE_EVENT", voltha.EventCategory_COMMUNICATION, nil, time.Now().Unix())
Kent Hagerman45a13e42020-04-13 12:23:50 -0400633 continue
634 }
635
Himani Chawlab4c25912020-11-12 17:16:38 +0530636 if agent := ldMgr.getLogicalDeviceAgent(pktCtx, packet.Id); agent != nil {
637 agent.packetOut(pktCtx, packet.PacketOut)
Kent Hagerman45a13e42020-04-13 12:23:50 -0400638 } else {
Himani Chawlab4c25912020-11-12 17:16:38 +0530639 logger.Errorf(ctx, "no-logical-device-agent-present", log.Fields{"logical-device-id": packet.Id})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400640 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400641 }
Kent Hagerman45a13e42020-04-13 12:23:50 -0400642
Himani Chawlab4c25912020-11-12 17:16:38 +0530643 logger.Debugw(ctx, "stream-packets-out-request-done", log.Fields{"packets": packets})
Kent Hagerman45a13e42020-04-13 12:23:50 -0400644 return nil
Kent Hagerman2b216042020-04-03 18:28:56 -0400645}
Himani Chawlab4c25912020-11-12 17:16:38 +0530646
647func (ldMgr *LogicalManager) SendRPCEvent(ctx context.Context, resourceID, desc string, context map[string]string,
648 id string, category voltha.EventCategory_Types, subCategory *voltha.EventSubCategory_Types, raisedTs int64) {
Mahir Gunyelb0343bf2021-05-11 14:14:26 -0700649 ldMgr.Manager.Agent.GetAndSendRPCEvent(ctx, resourceID, desc, context, id,
Himani Chawlab4c25912020-11-12 17:16:38 +0530650 category, subCategory, raisedTs)
651}