[VOL-4898] panic during device delete
- Also divided some functions into sub functions for cyclomatic complexity error in sca.
- Let the Device continue its initialization even if some PON ports indicated error.
Change-Id: I69dc8ed13570dad095ddb9fcccddf96de17e73d7
diff --git a/VERSION b/VERSION
index 27b8cad..9580abf 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.2.9
+4.2.10
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index e8ced1e..37c5397 100644
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-//Package core provides the utility for olt devices, flows and statistics
+// Package core provides the utility for olt devices, flows and statistics
package core
import (
@@ -76,7 +76,7 @@
heartbeatPath = "heartbeat"
)
-//DeviceHandler will interact with the OLT device.
+// DeviceHandler will interact with the OLT device.
type DeviceHandler struct {
cm *config.ConfigManager
device *voltha.Device
@@ -133,7 +133,7 @@
heartbeatSignature uint32
}
-//OnuDevice represents ONU related info
+// OnuDevice represents ONU related info
type OnuDevice struct {
deviceID string
deviceType string
@@ -156,10 +156,10 @@
stopChannel chan struct{}
}
-//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
-//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
-//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
-//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
+// McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
+// The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
+// There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
+// and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
type McastFlowOrGroupControlBlock struct {
ctx context.Context // Flow/group handler context
flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
@@ -179,7 +179,7 @@
"tx_bcast_packets",
}
-//NewOnuDevice creates a new Onu Device
+// NewOnuDevice creates a new Onu Device
func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool, adapterEndpoint string) *OnuDevice {
var device OnuDevice
device.deviceID = devID
@@ -193,7 +193,7 @@
return &device
}
-//NewDeviceHandler creates a new device handler
+// NewDeviceHandler creates a new device handler
func NewDeviceHandler(cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenOLT, cm *config.ConfigManager, cfg *conf.AdapterFlags) *DeviceHandler {
var dh DeviceHandler
ctx := context.Background()
@@ -354,7 +354,7 @@
return result
}
-//GetportLabel returns the label for the NNI and the PON port based on port number and port type
+// GetportLabel returns the label for the NNI and the PON port based on port number and port type
func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
switch portType {
@@ -1000,9 +1000,11 @@
for i = 0; i < dh.totalPonPorts+1; i++ {
// Instantiate flow manager
if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
- return olterrors.ErrFlowManagerInstantiating
+ //Continue to check the rest of the ports
+ logger.Errorw(ctx, "error-initializing-flow-manager-for-intf", log.Fields{"intfID": i, "device-id": dh.device.Id})
+ } else {
+ dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
}
- dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
}
/* TODO: Instantiate Alarm , stats , BW managers */
/* Instantiating Event Manager to handle Alarms and KPIs */
@@ -1111,7 +1113,7 @@
}
}
-//AdoptDevice adopts the OLT device
+// AdoptDevice adopts the OLT device
func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
dh.transitionMap = NewTransitionMap(dh)
logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
@@ -1130,7 +1132,7 @@
}
}
-//GetOfpDeviceInfo Gets the Ofp information of the given device
+// GetOfpDeviceInfo Gets the Ofp information of the given device
func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ca.SwitchCapability, error) {
return &ca.SwitchCapability{
Desc: &of.OfpDesc{
@@ -1156,7 +1158,11 @@
if err != nil {
return nil, err
}
+ if dh.flowMgr == nil || dh.flowMgr[ifID] == nil {
+ return nil, olterrors.NewErrNotFound("no-flow-manager-found", log.Fields{"intf-id": ifID, "parent-device-id": request.ParentDeviceId, "child-device-id": request.DeviceId}, nil).Log()
+ }
return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, request.TpInstancePath, request.OnuId, request.DeviceId)
+
}
func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
@@ -1407,8 +1413,8 @@
return nil
}
-//getChildDevice function can be used in general to get child device, if not found in cache the function will
-//get from core and update the cache and return the child device.
+// getChildDevice function can be used in general to get child device, if not found in cache the function will
+// get from core and update the cache and return the child device.
func (dh *DeviceHandler) getChildDevice(ctx context.Context, sn string, parentPortNo uint32) *OnuDevice {
var InCacheOnuDev *OnuDevice
dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
@@ -1812,12 +1818,12 @@
return ""
}
-//UpdateFlowsBulk upates the bulk flow
+// UpdateFlowsBulk upates the bulk flow
func (dh *DeviceHandler) UpdateFlowsBulk() error {
return olterrors.ErrNotImplemented
}
-//GetChildDevice returns the child device for given parent port and onu id
+// GetChildDevice returns the child device for given parent port and onu id
func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
logger.Debugw(ctx, "getchilddevice",
log.Fields{"pon-port": parentPort,
@@ -1911,7 +1917,11 @@
if flow_utils.HasGroup(flow) {
err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
} else {
- err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, false, nil)
+ if dh.flowMgr == nil || dh.flowMgr[intfID] == nil {
+ err = fmt.Errorf("flow-manager-uninitialized-%v", device.Id)
+ } else {
+ err = dh.flowMgr[intfID].RouteFlowToOnuChannel(ctx, flow, false, nil)
+ }
}
if err != nil {
if werr, ok := err.(olterrors.WrappedError); ok && status.Code(werr.Unwrap()) == codes.NotFound {
@@ -1992,7 +2002,7 @@
return errorsList
}
-//UpdateFlowsIncrementally updates the device flow
+// UpdateFlowsIncrementally updates the device flow
func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *of.FlowMetadata) error {
var errorsList []error
@@ -2013,11 +2023,11 @@
return nil
}
-//DisableDevice disables the given device
-//It marks the following for the given device:
-//Device-Handler Admin-State : down
-//Device Port-State: UNKNOWN
-//Device Oper-State: UNKNOWN
+// DisableDevice disables the given device
+// It marks the following for the given device:
+// Device-Handler Admin-State : down
+// Device Port-State: UNKNOWN
+// Device Oper-State: UNKNOWN
func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
/* On device disable ,admin state update has to be done prior sending request to agent since
the indication thread may processes invalid indications of ONU and OLT*/
@@ -2085,11 +2095,11 @@
}
-//ReenableDevice re-enables the olt device after disable
-//It marks the following for the given device:
-//Device-Handler Admin-State : up
-//Device Port-State: ACTIVE
-//Device Oper-State: ACTIVE
+// ReenableDevice re-enables the olt device after disable
+// It marks the following for the given device:
+// Device-Handler Admin-State : up
+// Device Port-State: ACTIVE
+// Device Oper-State: ACTIVE
func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
@@ -2140,8 +2150,12 @@
uniID = plt.UniIDFromPortNum(port)
logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
/* Delete tech-profile instance from the KV store */
- if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
- logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
+ if dh.flowMgr == nil || dh.flowMgr[onu.IntfID] == nil {
+ logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu-no-flowmng", log.Fields{"onu-id": onu.OnuID})
+ } else {
+ if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
+ logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
+ }
}
logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.OnuID, uniID)
@@ -2180,8 +2194,10 @@
wg.Add(1) // for the mcast routine below to finish
go dh.StopAllMcastHandlerRoutines(ctx, &wg)
for _, flMgr := range dh.flowMgr {
- wg.Add(1) // for the flow handler routine below to finish
- go flMgr.StopAllFlowHandlerRoutines(ctx, &wg)
+ if flMgr != nil {
+ wg.Add(1) // for the flow handler routine below to finish
+ go flMgr.StopAllFlowHandlerRoutines(ctx, &wg)
+ }
}
if !dh.waitForTimeoutOrCompletion(&wg, time.Second*30) {
logger.Warnw(ctx, "timed out waiting for stopping flow and group handlers", log.Fields{"deviceID": device.Id})
@@ -2272,7 +2288,7 @@
})
}
-//RebootDevice reboots the given device
+// RebootDevice reboots the given device
func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
@@ -2289,6 +2305,9 @@
"packet": hex.EncodeToString(packetIn.Pkt),
})
}
+ if dh.flowMgr == nil || dh.flowMgr[packetIn.IntfId] == nil {
+ return olterrors.NewErrNotFound("flow-manager", log.Fields{"intf-id": packetIn.IntfId, "packet": hex.EncodeToString(packetIn.Pkt)}, nil)
+ }
logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
if err != nil {
return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
@@ -2323,6 +2342,112 @@
return nil
}
+// PacketOutNNI sends packet-out from VOLTHA to OLT on the NNI provided
+func (dh *DeviceHandler) PacketOutNNI(ctx context.Context, egressPortNo uint32, packet *of.OfpPacketOut) error {
+ nniIntfID, err := plt.IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
+ if err != nil {
+ return olterrors.NewErrInvalidValue(log.Fields{
+ "egress-nni-port": egressPortNo,
+ "device-id": dh.device.Id,
+ }, err)
+ }
+ uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
+
+ if logger.V(log.DebugLevel) {
+ logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
+ "uplink-pkt": uplinkPkt,
+ "packet": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ })
+ }
+
+ if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
+ return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
+ "packet": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ }, err)
+ }
+ return nil
+}
+
+// PacketOutUNI sends packet-out from VOLTHA to OLT on the UNI provided
+func (dh *DeviceHandler) PacketOutUNI(ctx context.Context, egressPortNo uint32, packet *of.OfpPacketOut) error {
+ outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
+ innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
+ if outerEthType == 0x8942 || outerEthType == 0x88cc {
+ // Do not packet-out lldp packets on uni port.
+ // ONOS has no clue about uni/nni ports, it just packets out on all
+ // available ports on the Logical Switch. It should not be interested
+ // in the UNI links.
+ logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
+ "device-id": dh.device.Id,
+ })
+ return nil
+ }
+ if outerEthType == 0x88a8 || outerEthType == 0x8100 {
+ if innerEthType == 0x8100 {
+ // q-in-q 802.1ad or 802.1q double tagged packet.
+ // slice out the outer tag.
+ packet.Data = append(packet.Data[:12], packet.Data[16:]...)
+ if logger.V(log.DebugLevel) {
+ logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
+ "packet-data": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ })
+ }
+ }
+ }
+ intfID := plt.IntfIDFromUniPortNum(uint32(egressPortNo))
+ onuID := plt.OnuIDFromPortNum(uint32(egressPortNo))
+ uniID := plt.UniIDFromPortNum(uint32(egressPortNo))
+ var gemPortID uint32
+ err := olterrors.NewErrNotFound("no-flow-manager-found-for-packet-out", log.Fields{"device-id": dh.device.Id}, nil).(error)
+ if dh.flowMgr != nil && dh.flowMgr[intfID] != nil {
+ gemPortID, err = dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
+ }
+ if err != nil {
+ // In this case the openolt agent will receive the gemPortID as 0.
+ // The agent tries to retrieve the gemPortID in this case.
+ // This may not always succeed at the agent and packetOut may fail.
+ logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
+ "intf-id": intfID,
+ "onu-id": onuID,
+ "uni-id": uniID,
+ "packet": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ "error": err,
+ })
+ }
+
+ onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
+ if logger.V(log.DebugLevel) {
+ logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
+ "egress-port-no": egressPortNo,
+ "intf-id": intfID,
+ "onu-id": onuID,
+ "uni-id": uniID,
+ "gem-port-id": gemPortID,
+ "packet": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ })
+ }
+
+ if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
+ return olterrors.NewErrCommunication("packet-out-send", log.Fields{
+ "source": "adapter",
+ "destination": "onu",
+ "egress-port-number": egressPortNo,
+ "intf-id": intfID,
+ "oni-id": onuID,
+ "uni-id": uniID,
+ "gem-port-id": gemPortID,
+ "packet": hex.EncodeToString(packet.Data),
+ "device-id": dh.device.Id,
+ }, err)
+ }
+ return nil
+}
+
// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo uint32, packet *of.OfpPacketOut) error {
if logger.V(log.DebugLevel) {
@@ -2335,100 +2460,11 @@
}
egressPortType := plt.IntfIDToPortTypeName(uint32(egressPortNo))
+ var err error
if egressPortType == voltha.Port_ETHERNET_UNI {
- outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
- innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
- if outerEthType == 0x8942 || outerEthType == 0x88cc {
- // Do not packet-out lldp packets on uni port.
- // ONOS has no clue about uni/nni ports, it just packets out on all
- // available ports on the Logical Switch. It should not be interested
- // in the UNI links.
- logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
- "device-id": dh.device.Id,
- })
- return nil
- }
- if outerEthType == 0x88a8 || outerEthType == 0x8100 {
- if innerEthType == 0x8100 {
- // q-in-q 802.1ad or 802.1q double tagged packet.
- // slice out the outer tag.
- packet.Data = append(packet.Data[:12], packet.Data[16:]...)
- if logger.V(log.DebugLevel) {
- logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
- "packet-data": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- })
- }
- }
- }
- intfID := plt.IntfIDFromUniPortNum(uint32(egressPortNo))
- onuID := plt.OnuIDFromPortNum(uint32(egressPortNo))
- uniID := plt.UniIDFromPortNum(uint32(egressPortNo))
-
- gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
- if err != nil {
- // In this case the openolt agent will receive the gemPortID as 0.
- // The agent tries to retrieve the gemPortID in this case.
- // This may not always succeed at the agent and packetOut may fail.
- logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
- "intf-id": intfID,
- "onu-id": onuID,
- "uni-id": uniID,
- "packet": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- })
- }
-
- onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
- if logger.V(log.DebugLevel) {
- logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
- "egress-port-no": egressPortNo,
- "intf-id": intfID,
- "onu-id": onuID,
- "uni-id": uniID,
- "gem-port-id": gemPortID,
- "packet": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- })
- }
-
- if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
- return olterrors.NewErrCommunication("packet-out-send", log.Fields{
- "source": "adapter",
- "destination": "onu",
- "egress-port-number": egressPortNo,
- "intf-id": intfID,
- "oni-id": onuID,
- "uni-id": uniID,
- "gem-port-id": gemPortID,
- "packet": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- }, err)
- }
+ err = dh.PacketOutUNI(ctx, egressPortNo, packet)
} else if egressPortType == voltha.Port_ETHERNET_NNI {
- nniIntfID, err := plt.IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
- if err != nil {
- return olterrors.NewErrInvalidValue(log.Fields{
- "egress-nni-port": egressPortNo,
- "device-id": dh.device.Id,
- }, err)
- }
- uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
-
- if logger.V(log.DebugLevel) {
- logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
- "uplink-pkt": uplinkPkt,
- "packet": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- })
- }
-
- if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
- return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
- "packet": hex.EncodeToString(packet.Data),
- "device-id": dh.device.Id,
- }, err)
- }
+ err = dh.PacketOutNNI(ctx, egressPortNo, packet)
} else {
logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
"egress-port-no": egressPortNo,
@@ -2437,7 +2473,7 @@
"device-id": dh.device.Id,
})
}
- return nil
+ return err
}
func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
@@ -2638,8 +2674,10 @@
wg.Add(1) // for the multicast handler routine
go dh.StopAllMcastHandlerRoutines(ctx, &wg)
for _, flMgr := range dh.flowMgr {
- wg.Add(1) // for the flow handler routine
- go flMgr.StopAllFlowHandlerRoutines(ctx, &wg)
+ if flMgr != nil {
+ wg.Add(1) // for the flow handler routine
+ go flMgr.StopAllFlowHandlerRoutines(ctx, &wg)
+ }
}
if !dh.waitForTimeoutOrCompletion(&wg, time.Second*30) {
logger.Warnw(ctx, "timed out waiting for stopping flow and group handlers", log.Fields{"deviceID": device.Id})
@@ -2682,7 +2720,7 @@
return dh.modifyPhyPort(ctx, port, false)
}
-//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
+// modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
if port.GetType() == voltha.Port_ETHERNET_NNI {
@@ -2734,7 +2772,7 @@
return nil
}
-//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
+// disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
// Disable the port and update the oper_port_status to core
// if the Admin state of the port is disabled on reboot and re-enable device.
@@ -2750,7 +2788,7 @@
return nil
}
-//populateActivePorts to populate activePorts map
+// populateActivePorts to populate activePorts map
func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
for _, port := range ports {
@@ -2821,13 +2859,7 @@
}
}
if !alreadyRemoved {
- flow := &oop.Flow{FlowId: flowID}
- if err := dh.flowMgr[intfID].removeFlowFromDevice(ctx, flow, flowID); err != nil {
- logger.Warnw(ctx, "failed-to-remove-flow-from-device", log.Fields{
- "device-id": dh.device.Id,
- "onu-device": onu,
- "err": err})
- }
+ dh.removeFlowFromDevice(ctx, flowID, intfID)
removedFlows = appendUnique64bit(removedFlows, flowID)
}
}
@@ -2864,6 +2896,19 @@
return nil
}
+func (dh *DeviceHandler) removeFlowFromDevice(ctx context.Context, flowID uint64, intfID uint32) {
+ flow := &oop.Flow{FlowId: flowID}
+ if dh.flowMgr == nil || dh.flowMgr[intfID] == nil {
+ logger.Warnw(ctx, "failed-to-get-flow-mgr-to-remove-flow-from-device", log.Fields{
+ "device-id": dh.device.Id})
+ } else {
+ if err := dh.flowMgr[intfID].removeFlowFromDevice(ctx, flow, flowID); err != nil {
+ logger.Warnw(ctx, "failed-to-remove-flow-from-device", log.Fields{
+ "device-id": dh.device.Id,
+ "err": err})
+ }
+ }
+}
func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
for _, field := range flow_utils.GetOfbFields(flow) {
@@ -3102,16 +3147,28 @@
logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
log.Fields{"device-id": dh.device.Id,
"flowToAdd": mcastFlowOrGroupCb.flow})
- // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
- err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
+ err := olterrors.NewErrNotFound("no-flow-manager-found-to-add-mcast-flow", log.Fields{"device-id": dh.device.Id}, nil).(error)
+ // The mcast flow is not unique to any particular PON port, so it is OK to default to first non nil PON
+ for _, flMgr := range dh.flowMgr {
+ if flMgr != nil {
+ err = flMgr.AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
+ break
+ }
+ }
// Pass the return value over the return channel
*mcastFlowOrGroupCb.errChan <- err
} else { // flow remove
logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
log.Fields{"device-id": dh.device.Id,
"flowToRemove": mcastFlowOrGroupCb.flow})
- // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
- err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
+ // The mcast flow is not unique to any particular PON port, so it is OK to default to first non nil PON
+ err := olterrors.NewErrNotFound("no-flow-manager-found-to-remove-mcast-flow", log.Fields{"device-id": dh.device.Id}, nil).(error)
+ for _, flMgr := range dh.flowMgr {
+ if flMgr != nil {
+ err = flMgr.RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
+ break
+ }
+ }
// Pass the return value over the return channel
*mcastFlowOrGroupCb.errChan <- err
}