blob: b871cd4ab6eb7b712c35c288bd0d1eec0c04f26e [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 */
16package core
17
18import (
19 "context"
20 "errors"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/db/model"
23 "github.com/opencord/voltha-go/kafka"
William Kurkiandaa6bb22019-03-07 12:26:28 -050024 "github.com/opencord/voltha-protos/go/openflow_13"
25 "github.com/opencord/voltha-protos/go/voltha"
khenaidoob9203542018-09-17 22:56:37 -040026 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
khenaidoob9203542018-09-17 22:56:37 -040028 "strings"
29 "sync"
30)
31
32type LogicalDeviceManager struct {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040033 logicalDeviceAgents sync.Map
34 core *Core
35 deviceMgr *DeviceManager
36 grpcNbiHdlr *APIHandler
37 adapterProxy *AdapterProxy
38 kafkaICProxy *kafka.InterContainerProxy
39 clusterDataProxy *model.Proxy
40 exitChannel chan int
41 defaultTimeout int64
khenaidoob9203542018-09-17 22:56:37 -040042}
43
khenaidoo2c6a0992019-04-29 13:46:56 -040044func newLogicalDeviceManager(core *Core, deviceMgr *DeviceManager, kafkaICProxy *kafka.InterContainerProxy, cdProxy *model.Proxy, timeout int64) *LogicalDeviceManager {
khenaidoob9203542018-09-17 22:56:37 -040045 var logicalDeviceMgr LogicalDeviceManager
Richard Jankowski199fd862019-03-18 14:49:51 -040046 logicalDeviceMgr.core = core
khenaidoob9203542018-09-17 22:56:37 -040047 logicalDeviceMgr.exitChannel = make(chan int, 1)
khenaidoob9203542018-09-17 22:56:37 -040048 logicalDeviceMgr.deviceMgr = deviceMgr
khenaidoo43c82122018-11-22 18:38:28 -050049 logicalDeviceMgr.kafkaICProxy = kafkaICProxy
khenaidoo9a468962018-09-19 15:33:13 -040050 logicalDeviceMgr.clusterDataProxy = cdProxy
khenaidoo2c6a0992019-04-29 13:46:56 -040051 logicalDeviceMgr.defaultTimeout = timeout
khenaidoob9203542018-09-17 22:56:37 -040052 return &logicalDeviceMgr
53}
54
Richard Jankowskidbab94a2018-12-06 16:20:25 -050055func (ldMgr *LogicalDeviceManager) setGrpcNbiHandler(grpcNbiHandler *APIHandler) {
56 ldMgr.grpcNbiHdlr = grpcNbiHandler
57}
58
khenaidoo4d4802d2018-10-04 21:59:49 -040059func (ldMgr *LogicalDeviceManager) start(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040060 log.Info("starting-logical-device-manager")
61 log.Info("logical-device-manager-started")
62}
63
khenaidoo4d4802d2018-10-04 21:59:49 -040064func (ldMgr *LogicalDeviceManager) stop(ctx context.Context) {
khenaidoob9203542018-09-17 22:56:37 -040065 log.Info("stopping-logical-device-manager")
66 ldMgr.exitChannel <- 1
67 log.Info("logical-device-manager-stopped")
68}
69
khenaidoo19d7b632018-10-30 10:49:50 -040070func sendAPIResponse(ctx context.Context, ch chan interface{}, result interface{}) {
71 if ctx.Err() == nil {
72 // Returned response only of the ctx has not been cancelled/timeout/etc
73 // Channel is automatically closed when a context is Done
74 ch <- result
75 log.Debugw("sendResponse", log.Fields{"result": result})
76 } else {
77 // Should the transaction be reverted back?
78 log.Debugw("sendResponse-context-error", log.Fields{"context-error": ctx.Err()})
79 }
80}
81
khenaidoob9203542018-09-17 22:56:37 -040082func (ldMgr *LogicalDeviceManager) addLogicalDeviceAgentToMap(agent *LogicalDeviceAgent) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040083 if _, exist := ldMgr.logicalDeviceAgents.Load(agent.logicalDeviceId); !exist {
84 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceId, agent)
khenaidoob9203542018-09-17 22:56:37 -040085 }
86}
87
khenaidoo6d62c002019-05-15 21:57:03 -040088func (ldMgr *LogicalDeviceManager) isLogicalDeviceInCache(logicalDeviceId string) bool {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040089 _, inCache := ldMgr.logicalDeviceAgents.Load(logicalDeviceId)
khenaidoo6d62c002019-05-15 21:57:03 -040090 return inCache
91}
92
khenaidoo8c3303d2019-02-13 14:59:39 -050093// getLogicalDeviceAgent returns the logical device agent. If the device is not in memory then the device will
94// be loaded from dB and a logical device agent created to managed it.
khenaidoob9203542018-09-17 22:56:37 -040095func (ldMgr *LogicalDeviceManager) getLogicalDeviceAgent(logicalDeviceId string) *LogicalDeviceAgent {
Stephane Barbarieef6650d2019-07-18 12:15:09 -040096 if agent, ok := ldMgr.logicalDeviceAgents.Load(logicalDeviceId); ok {
97 return agent.(*LogicalDeviceAgent)
khenaidoo8c3303d2019-02-13 14:59:39 -050098 } else {
99 // Try to load into memory - loading will also create the logical device agent
khenaidoo8c3303d2019-02-13 14:59:39 -0500100 if err := ldMgr.load(logicalDeviceId); err == nil {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400101 if agent, ok = ldMgr.logicalDeviceAgents.Load(logicalDeviceId); ok {
102 return agent.(*LogicalDeviceAgent)
khenaidoo8c3303d2019-02-13 14:59:39 -0500103 }
104 }
khenaidoob9203542018-09-17 22:56:37 -0400105 }
106 return nil
107}
108
khenaidoo92e62c52018-10-03 14:02:54 -0400109func (ldMgr *LogicalDeviceManager) deleteLogicalDeviceAgent(logicalDeviceId string) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400110 ldMgr.logicalDeviceAgents.Delete(logicalDeviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400111}
112
khenaidoo8c3303d2019-02-13 14:59:39 -0500113// GetLogicalDevice provides a cloned most up to date logical device. If device is not in memory
114// it will be fetched from the dB
khenaidoob9203542018-09-17 22:56:37 -0400115func (ldMgr *LogicalDeviceManager) getLogicalDevice(id string) (*voltha.LogicalDevice, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400116 log.Debugw("getlogicalDevice", log.Fields{"logicaldeviceid": id})
117 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
khenaidoo19d7b632018-10-30 10:49:50 -0400118 return agent.GetLogicalDevice()
khenaidoob9203542018-09-17 22:56:37 -0400119 }
120 return nil, status.Errorf(codes.NotFound, "%s", id)
121}
122
khenaidoo43aa6bd2019-05-29 13:35:13 -0400123func (ldMgr *LogicalDeviceManager) listManagedLogicalDevices() (*voltha.LogicalDevices, error) {
124 log.Debug("listManagedLogicalDevices")
125 result := &voltha.LogicalDevices{}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400126 ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
127 agent := value.(*LogicalDeviceAgent)
khenaidoo43aa6bd2019-05-29 13:35:13 -0400128 if ld, _ := agent.GetLogicalDevice(); ld != nil {
129 result.Items = append(result.Items, ld)
130 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400131 return true
132 })
133
khenaidoo43aa6bd2019-05-29 13:35:13 -0400134 return result, nil
135}
136
khenaidoob9203542018-09-17 22:56:37 -0400137func (ldMgr *LogicalDeviceManager) listLogicalDevices() (*voltha.LogicalDevices, error) {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500138 log.Debug("ListAllLogicalDevices")
khenaidoob9203542018-09-17 22:56:37 -0400139 result := &voltha.LogicalDevices{}
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400140 if logicalDevices := ldMgr.clusterDataProxy.List(context.Background(), "/logical_devices", 0, false, ""); logicalDevices != nil {
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500141 for _, logicalDevice := range logicalDevices.([]interface{}) {
142 if agent := ldMgr.getLogicalDeviceAgent(logicalDevice.(*voltha.LogicalDevice).Id); agent == nil {
143 agent = newLogicalDeviceAgent(
144 logicalDevice.(*voltha.LogicalDevice).Id,
145 logicalDevice.(*voltha.LogicalDevice).RootDeviceId,
146 ldMgr,
147 ldMgr.deviceMgr,
148 ldMgr.clusterDataProxy,
khenaidoo2c6a0992019-04-29 13:46:56 -0400149 ldMgr.defaultTimeout,
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500150 )
151 ldMgr.addLogicalDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500152 go agent.start(nil, true)
Stephane Barbarie1ab43272018-12-08 21:42:13 -0500153 }
154 result.Items = append(result.Items, logicalDevice.(*voltha.LogicalDevice))
khenaidoob9203542018-09-17 22:56:37 -0400155 }
156 }
157 return result, nil
158}
159
khenaidoo4d4802d2018-10-04 21:59:49 -0400160func (ldMgr *LogicalDeviceManager) createLogicalDevice(ctx context.Context, device *voltha.Device) (*string, error) {
khenaidoo92e62c52018-10-03 14:02:54 -0400161 log.Debugw("creating-logical-device", log.Fields{"deviceId": device.Id})
khenaidoob9203542018-09-17 22:56:37 -0400162 // Sanity check
163 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400164 return nil, errors.New("device-not-root")
khenaidoob9203542018-09-17 22:56:37 -0400165 }
166
167 // Create a logical device agent - the logical device Id is based on the mac address of the device
168 // For now use the serial number - it may contain any combination of alphabetic characters and numbers,
169 // with length varying from eight characters to a maximum of 14 characters. Mac Address is part of oneof
170 // in the Device model. May need to be moved out.
171 macAddress := device.MacAddress
172 id := strings.Replace(macAddress, ":", "", -1)
khenaidoo92e62c52018-10-03 14:02:54 -0400173 if id == "" {
174 log.Errorw("mac-address-not-set", log.Fields{"deviceId": device.Id})
175 return nil, errors.New("mac-address-not-set")
176 }
177 log.Debugw("logical-device-id", log.Fields{"logicaldeviceId": id})
khenaidoob9203542018-09-17 22:56:37 -0400178
khenaidoo2c6a0992019-04-29 13:46:56 -0400179 agent := newLogicalDeviceAgent(id, device.Id, ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
khenaidoob9203542018-09-17 22:56:37 -0400180 ldMgr.addLogicalDeviceAgentToMap(agent)
khenaidoo297cd252019-02-07 22:10:23 -0500181 go agent.start(ctx, false)
khenaidoob9203542018-09-17 22:56:37 -0400182
khenaidoo92e62c52018-10-03 14:02:54 -0400183 log.Debug("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
190func (ldMgr *LogicalDeviceManager) stopManagingLogicalDeviceWithDeviceId(id string) string {
191 log.Infow("stop-managing-logical-device", log.Fields{"deviceId": id})
192 // Go over the list of logical device agents to find the one which has rootDeviceId as id
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400193 var ldId = ""
194 ldMgr.logicalDeviceAgents.Range(func(key, value interface{}) bool {
195 ldAgent := value.(*LogicalDeviceAgent)
khenaidoo6d62c002019-05-15 21:57:03 -0400196 if ldAgent.rootDeviceId == id {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400197 log.Infow("stopping-logical-device-agent", log.Fields{"lDeviceId": key})
khenaidoo6d62c002019-05-15 21:57:03 -0400198 ldAgent.stop(nil)
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400199 ldMgr.logicalDeviceAgents.Delete(ldId)
200 ldId = key.(string)
khenaidoo6d62c002019-05-15 21:57:03 -0400201 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400202 return true
203 })
204 return ldId
khenaidoo6d62c002019-05-15 21:57:03 -0400205}
206
207//getLogicalDeviceFromModel retrieves the logical device data from the model.
208func (ldMgr *LogicalDeviceManager) getLogicalDeviceFromModel(lDeviceId string) (*voltha.LogicalDevice, error) {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400209 if logicalDevice := ldMgr.clusterDataProxy.Get(context.Background(), "/logical_devices/"+lDeviceId, 0, false, ""); logicalDevice != nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400210 if lDevice, ok := logicalDevice.(*voltha.LogicalDevice); ok {
211 return lDevice, nil
212 }
213 }
214 return nil, status.Error(codes.NotFound, lDeviceId)
215}
216
khenaidoo297cd252019-02-07 22:10:23 -0500217// load loads a logical device manager in memory
218func (ldMgr *LogicalDeviceManager) load(lDeviceId string) error {
khenaidoo1ce37ad2019-03-24 22:07:24 -0400219 log.Debugw("loading-logical-device", log.Fields{"lDeviceId": lDeviceId})
khenaidoo297cd252019-02-07 22:10:23 -0500220 // To prevent a race condition, let's hold the logical device agent map lock. This will prevent a loading and
221 // a create logical device callback from occurring at the same time.
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400222 if ldAgent, _ := ldMgr.logicalDeviceAgents.Load(lDeviceId); ldAgent == nil {
khenaidoo6d62c002019-05-15 21:57:03 -0400223 // Proceed with the loading only if the logical device exist in the Model (could have been deleted)
224 if _, err := ldMgr.getLogicalDeviceFromModel(lDeviceId); err == nil {
225 // Create a temp logical device Agent and let it load from memory
226 agent := newLogicalDeviceAgent(lDeviceId, "", ldMgr, ldMgr.deviceMgr, ldMgr.clusterDataProxy, ldMgr.defaultTimeout)
227 if err := agent.start(nil, true); err != nil {
228 agent.stop(nil)
229 return err
230 }
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400231 ldMgr.logicalDeviceAgents.Store(agent.logicalDeviceId, agent)
khenaidoo297cd252019-02-07 22:10:23 -0500232 }
khenaidoo297cd252019-02-07 22:10:23 -0500233 }
234 // TODO: load the child device
235 return nil
236}
237
khenaidoo4d4802d2018-10-04 21:59:49 -0400238func (ldMgr *LogicalDeviceManager) deleteLogicalDevice(ctx context.Context, device *voltha.Device) error {
khenaidoo92e62c52018-10-03 14:02:54 -0400239 log.Debugw("deleting-logical-device", log.Fields{"deviceId": device.Id})
240 // Sanity check
241 if !device.Root {
khenaidoo2c6a0992019-04-29 13:46:56 -0400242 return errors.New("device-not-root")
khenaidoo92e62c52018-10-03 14:02:54 -0400243 }
244 logDeviceId := device.ParentId
245 if agent := ldMgr.getLogicalDeviceAgent(logDeviceId); agent != nil {
246 // Stop the logical device agent
khenaidoo4d4802d2018-10-04 21:59:49 -0400247 agent.stop(ctx)
khenaidoo92e62c52018-10-03 14:02:54 -0400248 //Remove the logical device agent from the Map
249 ldMgr.deleteLogicalDeviceAgent(logDeviceId)
Richard Jankowski199fd862019-03-18 14:49:51 -0400250 ldMgr.core.deviceOwnership.AbandonDevice(logDeviceId)
khenaidoo92e62c52018-10-03 14:02:54 -0400251 }
252
253 log.Debug("deleting-logical-device-ends")
254 return nil
255}
256
257func (ldMgr *LogicalDeviceManager) getLogicalDeviceId(device *voltha.Device) (*string, error) {
258 // Device can either be a parent or a child device
259 if device.Root {
260 // Parent device. The ID of a parent device is the logical device ID
261 return &device.ParentId, nil
262 }
263 // Device is child device
264 // retrieve parent device using child device ID
265 if parentDevice := ldMgr.deviceMgr.getParentDevice(device); parentDevice != nil {
266 return &parentDevice.ParentId, nil
267 }
268 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
269}
270
khenaidoo3ab34882019-05-02 21:33:30 -0400271func (ldMgr *LogicalDeviceManager) getLogicalDeviceIdFromDeviceId(deviceId string) (*string, error) {
272 // Get the device
273 var device *voltha.Device
274 var err error
275 if device, err = ldMgr.deviceMgr.GetDevice(deviceId); err != nil {
276 return nil, err
277 }
278 return ldMgr.getLogicalDeviceId(device)
279}
280
khenaidoo19d7b632018-10-30 10:49:50 -0400281func (ldMgr *LogicalDeviceManager) getLogicalPortId(device *voltha.Device) (*voltha.LogicalPortId, error) {
282 // Get the logical device where this device is attached
283 var lDeviceId *string
284 var err error
285 if lDeviceId, err = ldMgr.getLogicalDeviceId(device); err != nil {
286 return nil, err
287 }
288 var lDevice *voltha.LogicalDevice
289 if lDevice, err = ldMgr.getLogicalDevice(*lDeviceId); err != nil {
290 return nil, err
291 }
292 // Go over list of ports
293 for _, port := range lDevice.Ports {
294 if port.DeviceId == device.Id {
295 return &voltha.LogicalPortId{Id: *lDeviceId, PortId: port.Id}, nil
296 }
297 }
298 return nil, status.Errorf(codes.NotFound, "%s", device.Id)
299}
300
khenaidoodd237172019-05-27 16:37:17 -0400301func (ldMgr *LogicalDeviceManager) ListLogicalDeviceFlows(ctx context.Context, id string) (*openflow_13.Flows, error) {
302 log.Debugw("ListLogicalDeviceFlows", log.Fields{"logicaldeviceid": id})
303 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
304 return agent.ListLogicalDeviceFlows()
305 }
306 return nil, status.Errorf(codes.NotFound, "%s", id)
307}
308
309func (ldMgr *LogicalDeviceManager) ListLogicalDeviceFlowGroups(ctx context.Context, id string) (*openflow_13.FlowGroups, error) {
310 log.Debugw("ListLogicalDeviceFlowGroups", log.Fields{"logicaldeviceid": id})
311 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
312 return agent.ListLogicalDeviceFlowGroups()
313 }
314 return nil, status.Errorf(codes.NotFound, "%s", id)
315}
316
khenaidoo19d7b632018-10-30 10:49:50 -0400317func (ldMgr *LogicalDeviceManager) ListLogicalDevicePorts(ctx context.Context, id string) (*voltha.LogicalPorts, error) {
318 log.Debugw("ListLogicalDevicePorts", log.Fields{"logicaldeviceid": id})
319 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
320 return agent.ListLogicalDevicePorts()
321 }
322 return nil, status.Errorf(codes.NotFound, "%s", id)
khenaidoo19d7b632018-10-30 10:49:50 -0400323}
324
325func (ldMgr *LogicalDeviceManager) getLogicalPort(lPortId *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
326 // Get the logical device where this device is attached
327 var err error
328 var lDevice *voltha.LogicalDevice
329 if lDevice, err = ldMgr.getLogicalDevice(lPortId.Id); err != nil {
330 return nil, err
331 }
332 // Go over list of ports
333 for _, port := range lDevice.Ports {
334 if port.Id == lPortId.PortId {
335 return port, nil
336 }
337 }
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400338 return nil, status.Errorf(codes.NotFound, "%s-%s", lPortId.Id, lPortId.PortId)
khenaidoo19d7b632018-10-30 10:49:50 -0400339}
340
khenaidoo2c6a0992019-04-29 13:46:56 -0400341// updateLogicalPort sets up a logical port on the logical device based on the device port
342// information, if needed
343func (ldMgr *LogicalDeviceManager) updateLogicalPort(device *voltha.Device, port *voltha.Port) error {
344 if ldID, err := ldMgr.getLogicalDeviceId(device); err != nil || *ldID == "" {
345 // This is not an error as the logical device may not have been created at this time. In such a case,
346 // the ports will be created when the logical device is ready.
347 return nil
348 } else {
349 if agent := ldMgr.getLogicalDeviceAgent(*ldID); agent != nil {
350 if err := agent.updateLogicalPort(device, port); err != nil {
351 return err
352 }
353 }
354 }
355 return nil
356}
357
khenaidoofc1314d2019-03-14 09:34:21 -0400358// addLogicalPort sets up a logical port on the logical device based on the device port
359// information.
360func (ldMgr *LogicalDeviceManager) addLogicalPort(device *voltha.Device, port *voltha.Port) error {
Stephane Barbarie40fd3b22019-04-23 21:50:47 -0400361 if ldID, err := ldMgr.getLogicalDeviceId(device); err != nil || *ldID == "" {
khenaidoofc1314d2019-03-14 09:34:21 -0400362 // This is not an error as the logical device may not have been created at this time. In such a case,
363 // the ports will be created when the logical device is ready.
364 return nil
365 } else {
366 if agent := ldMgr.getLogicalDeviceAgent(*ldID); agent != nil {
367 if err := agent.addLogicalPort(device, port); err != nil {
368 return err
369 }
370 }
371 }
372 return nil
373}
374
khenaidoo0a822f92019-05-08 15:15:57 -0400375// deleteLogicalPort removes the logical port associated with a device
khenaidoo19d7b632018-10-30 10:49:50 -0400376func (ldMgr *LogicalDeviceManager) deleteLogicalPort(ctx context.Context, lPortId *voltha.LogicalPortId) error {
377 log.Debugw("deleting-logical-port", log.Fields{"LDeviceId": lPortId.Id})
378 // Get logical port
379 var logicalPort *voltha.LogicalPort
380 var err error
381 if logicalPort, err = ldMgr.getLogicalPort(lPortId); err != nil {
382 log.Debugw("no-logical-device-port-present", log.Fields{"logicalPortId": lPortId.PortId})
383 return err
384 }
khenaidoo92e62c52018-10-03 14:02:54 -0400385 // Sanity check
khenaidoo19d7b632018-10-30 10:49:50 -0400386 if logicalPort.RootPort {
khenaidoo2c6a0992019-04-29 13:46:56 -0400387 return errors.New("device-root")
khenaidoo92e62c52018-10-03 14:02:54 -0400388 }
khenaidoo19d7b632018-10-30 10:49:50 -0400389 if agent := ldMgr.getLogicalDeviceAgent(lPortId.Id); agent != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400390 if err := agent.deleteLogicalPort(logicalPort); err != nil {
391 log.Warnw("deleting-logicalport-failed", log.Fields{"LDeviceId": lPortId.Id, "error": err})
392 }
khenaidoo92e62c52018-10-03 14:02:54 -0400393 }
394
395 log.Debug("deleting-logical-port-ends")
396 return nil
397}
398
khenaidoo0a822f92019-05-08 15:15:57 -0400399// deleteLogicalPort removes the logical port associated with a child device
400func (ldMgr *LogicalDeviceManager) deleteLogicalPorts(deviceId string) error {
401 log.Debugw("deleting-logical-ports", log.Fields{"deviceId": deviceId})
402 // Get logical port
403 if ldId, err := ldMgr.getLogicalDeviceIdFromDeviceId(deviceId); err != nil {
khenaidoo0a822f92019-05-08 15:15:57 -0400404 return err
405 } else {
406 if agent := ldMgr.getLogicalDeviceAgent(*ldId); agent != nil {
407 if err = agent.deleteLogicalPorts(deviceId); err != nil {
408 log.Warnw("deleteLogicalPorts-failed", log.Fields{"ldeviceId": *ldId})
409 return err
410 }
411 }
412 }
413 log.Debug("deleting-logical-port-ends")
414 return nil
415}
416
khenaidoofc1314d2019-03-14 09:34:21 -0400417func (ldMgr *LogicalDeviceManager) setupUNILogicalPorts(ctx context.Context, childDevice *voltha.Device) error {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400418 log.Debugw("setupUNILogicalPorts", log.Fields{"childDeviceId": childDevice.Id, "parentDeviceId": childDevice.ParentId, "current-data": childDevice})
khenaidoob9203542018-09-17 22:56:37 -0400419 // Sanity check
420 if childDevice.Root {
421 return errors.New("Device-root")
422 }
423
424 // Get the logical device id parent device
425 parentId := childDevice.ParentId
426 logDeviceId := ldMgr.deviceMgr.GetParentDeviceId(parentId)
427
khenaidoofc1314d2019-03-14 09:34:21 -0400428 log.Debugw("setupUNILogicalPorts", log.Fields{"logDeviceId": logDeviceId, "parentId": parentId})
khenaidoob9203542018-09-17 22:56:37 -0400429
khenaidoo3d3b8c22019-05-22 18:10:39 -0400430 if parentId == "" || logDeviceId == nil || *logDeviceId == "" {
khenaidoo2c6a0992019-04-29 13:46:56 -0400431 return errors.New("device-in-invalid-state")
khenaidoo5e677ae2019-02-28 17:26:29 -0500432 }
433
khenaidoob9203542018-09-17 22:56:37 -0400434 if agent := ldMgr.getLogicalDeviceAgent(*logDeviceId); agent != nil {
khenaidoofc1314d2019-03-14 09:34:21 -0400435 if err := agent.setupUNILogicalPorts(ctx, childDevice); err != nil {
khenaidoobcf205b2019-01-25 22:21:14 -0500436 return err
437 }
khenaidoob9203542018-09-17 22:56:37 -0400438 }
khenaidoo21d51152019-02-01 13:48:37 -0500439 return nil
khenaidoob9203542018-09-17 22:56:37 -0400440}
khenaidoo19d7b632018-10-30 10:49:50 -0400441
khenaidoo0a822f92019-05-08 15:15:57 -0400442func (ldMgr *LogicalDeviceManager) deleteAllLogicalPorts(device *voltha.Device) error {
443 log.Debugw("deleteAllLogicalPorts", log.Fields{"deviceId": device.Id})
444
445 var ldId *string
446 var err error
447 //Get the logical device Id for this device
448 if ldId, err = ldMgr.getLogicalDeviceId(device); err != nil {
449 log.Warnw("no-logical-device-found", log.Fields{"deviceId": device.Id, "error": err})
450 return err
451 }
452 if agent := ldMgr.getLogicalDeviceAgent(*ldId); agent != nil {
453 if err := agent.deleteAllLogicalPorts(device); err != nil {
454 return err
455 }
456 }
457 return nil
458}
459
khenaidoo3ab34882019-05-02 21:33:30 -0400460func (ldMgr *LogicalDeviceManager) updatePortsState(device *voltha.Device, state voltha.AdminState_AdminState) error {
Stephane Barbarieef6650d2019-07-18 12:15:09 -0400461 log.Debugw("updatePortsState", log.Fields{"deviceId": device.Id, "state": state, "current-data": device})
khenaidoo3ab34882019-05-02 21:33:30 -0400462
463 var ldId *string
464 var err error
465 //Get the logical device Id for this device
466 if ldId, err = ldMgr.getLogicalDeviceId(device); err != nil {
467 log.Warnw("no-logical-device-found", log.Fields{"deviceId": device.Id, "error": err})
468 return err
469 }
470 if agent := ldMgr.getLogicalDeviceAgent(*ldId); agent != nil {
471 if err := agent.updatePortsState(device, state); err != nil {
472 return err
473 }
474 }
475 return nil
476}
477
khenaidoo19d7b632018-10-30 10:49:50 -0400478func (ldMgr *LogicalDeviceManager) updateFlowTable(ctx context.Context, id string, flow *openflow_13.OfpFlowMod, ch chan interface{}) {
479 log.Debugw("updateFlowTable", log.Fields{"logicalDeviceId": id})
480 var res interface{}
481 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
482 res = agent.updateFlowTable(ctx, flow)
483 log.Debugw("updateFlowTable-result", log.Fields{"result": res})
484 } else {
485 res = status.Errorf(codes.NotFound, "%s", id)
486 }
487 sendAPIResponse(ctx, ch, res)
488}
489
490func (ldMgr *LogicalDeviceManager) updateGroupTable(ctx context.Context, id string, groupMod *openflow_13.OfpGroupMod, ch chan interface{}) {
491 log.Debugw("updateGroupTable", log.Fields{"logicalDeviceId": id})
492 var res interface{}
493 if agent := ldMgr.getLogicalDeviceAgent(id); agent != nil {
494 res = agent.updateGroupTable(ctx, groupMod)
495 log.Debugw("updateGroupTable-result", log.Fields{"result": res})
496 } else {
497 res = status.Errorf(codes.NotFound, "%s", id)
498 }
499 sendAPIResponse(ctx, ch, res)
500}
501
502func (ldMgr *LogicalDeviceManager) enableLogicalPort(ctx context.Context, id *voltha.LogicalPortId, ch chan interface{}) {
503 log.Debugw("enableLogicalPort", log.Fields{"logicalDeviceId": id})
504 var res interface{}
505 // Get logical port
506 var logicalPort *voltha.LogicalPort
507 var err error
508 if logicalPort, err = ldMgr.getLogicalPort(id); err != nil {
509 log.Debugw("no-logical-device-port-present", log.Fields{"logicalPortId": id.PortId})
510 res = err
511 }
512 if agent := ldMgr.getLogicalDeviceAgent(id.Id); agent != nil {
513 res = agent.enableLogicalPort(logicalPort)
514 log.Debugw("enableLogicalPort-result", log.Fields{"result": res})
515 } else {
516 res = status.Errorf(codes.NotFound, "%s", id.Id)
517 }
518 sendAPIResponse(ctx, ch, res)
519}
520
521func (ldMgr *LogicalDeviceManager) disableLogicalPort(ctx context.Context, id *voltha.LogicalPortId, ch chan interface{}) {
522 log.Debugw("disableLogicalPort", log.Fields{"logicalDeviceId": id})
523 var res interface{}
524 // Get logical port
525 var logicalPort *voltha.LogicalPort
526 var err error
527 if logicalPort, err = ldMgr.getLogicalPort(id); err != nil {
528 log.Debugw("no-logical-device-port-present", log.Fields{"logicalPortId": id.PortId})
529 res = err
530 }
531 if agent := ldMgr.getLogicalDeviceAgent(id.Id); agent != nil {
532 res = agent.disableLogicalPort(logicalPort)
533 log.Debugw("disableLogicalPort-result", log.Fields{"result": res})
534 } else {
535 res = status.Errorf(codes.NotFound, "%s", id.Id)
536 }
537 sendAPIResponse(ctx, ch, res)
538}
khenaidoofdbad6e2018-11-06 22:26:38 -0500539
khenaidoo43c82122018-11-22 18:38:28 -0500540func (ldMgr *LogicalDeviceManager) packetOut(packetOut *openflow_13.PacketOut) {
khenaidoofdbad6e2018-11-06 22:26:38 -0500541 log.Debugw("packetOut", log.Fields{"logicalDeviceId": packetOut.Id})
542 if agent := ldMgr.getLogicalDeviceAgent(packetOut.Id); agent != nil {
543 agent.packetOut(packetOut.PacketOut)
544 } else {
545 log.Error("logical-device-not-exist", log.Fields{"logicalDeviceId": packetOut.Id})
546 }
547}
548
khenaidoo297cd252019-02-07 22:10:23 -0500549func (ldMgr *LogicalDeviceManager) packetIn(logicalDeviceId string, port uint32, transactionId string, packet []byte) error {
khenaidoofdbad6e2018-11-06 22:26:38 -0500550 log.Debugw("packetIn", log.Fields{"logicalDeviceId": logicalDeviceId, "port": port})
551 if agent := ldMgr.getLogicalDeviceAgent(logicalDeviceId); agent != nil {
khenaidoo297cd252019-02-07 22:10:23 -0500552 agent.packetIn(port, transactionId, packet)
khenaidoofdbad6e2018-11-06 22:26:38 -0500553 } else {
554 log.Error("logical-device-not-exist", log.Fields{"logicalDeviceId": logicalDeviceId})
555 }
556 return nil
557}