VOL-3121 - Separated out logical ports from logical agent.
Similar to flows/groups/meters.
Also modified device_route tests to generate unique port IDs (`.OfpPort.PortNo`s) across all UNI ports withing each test, i.e. within an OLT.
Also replaced logicalPortsNo map & associated NNI vs UNI logic with root device checks.
Change-Id: Ib0cecbf7d4f8d509ce7c989b9ccf697c8b0d17d6
diff --git a/rw_core/route/device_route.go b/rw_core/route/device_route.go
index 3cb8470..5cd75f2 100644
--- a/rw_core/route/device_route.go
+++ b/rw_core/route/device_route.go
@@ -20,11 +20,12 @@
"context"
"errors"
"fmt"
+ "sync"
+
"github.com/opencord/voltha-lib-go/v3/pkg/log"
"github.com/opencord/voltha-protos/v3/go/voltha"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
- "sync"
)
var ErrNoRoute = errors.New("no route")
@@ -119,7 +120,7 @@
}
//ComputeRoutes calculates all the routes between the logical ports. This will clear up any existing route
-func (dr *DeviceRoutes) ComputeRoutes(ctx context.Context, lps []*voltha.LogicalPort) error {
+func (dr *DeviceRoutes) ComputeRoutes(ctx context.Context, lps map[uint32]*voltha.LogicalPort) error {
dr.routeBuildLock.Lock()
defer dr.routeBuildLock.Unlock()
@@ -208,7 +209,7 @@
// AddPort augments the current set of routes with new routes corresponding to the logical port "lp". If the routes have
// not been built yet then use logical port "lps" to compute all current routes (lps includes lp)
-func (dr *DeviceRoutes) AddPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps []*voltha.LogicalPort) error {
+func (dr *DeviceRoutes) AddPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps map[uint32]*voltha.LogicalPort) error {
logger.Debugw("add-port-to-routes", log.Fields{"port": lp, "count-logical-ports": len(lps)})
// Adding NNI port
@@ -221,7 +222,7 @@
}
// AddUNIPort setup routes between the logical UNI port lp and all registered NNI ports
-func (dr *DeviceRoutes) AddUNIPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps []*voltha.LogicalPort) error {
+func (dr *DeviceRoutes) AddUNIPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps map[uint32]*voltha.LogicalPort) error {
logger.Debugw("add-uni-port-to-routes", log.Fields{"port": lp, "count-logical-ports": len(lps)})
dr.routeBuildLock.Lock()
@@ -258,7 +259,7 @@
}
// AddNNIPort setup routes between the logical NNI port lp and all registered UNI ports
-func (dr *DeviceRoutes) AddNNIPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps []*voltha.LogicalPort) error {
+func (dr *DeviceRoutes) AddNNIPort(ctx context.Context, lp *voltha.LogicalPort, device *voltha.Device, lps map[uint32]*voltha.LogicalPort) error {
logger.Debugw("add-port-to-routes", log.Fields{"port": lp, "logical-ports-count": len(lps), "device-id": device.Id})
dr.routeBuildLock.Lock()
@@ -316,7 +317,7 @@
}
// AddAllPorts setups up new routes using all ports on the device. lps includes the device's logical port
-func (dr *DeviceRoutes) AddAllPorts(ctx context.Context, device *voltha.Device, lps []*voltha.LogicalPort) error {
+func (dr *DeviceRoutes) AddAllPorts(ctx context.Context, device *voltha.Device, lps map[uint32]*voltha.LogicalPort) error {
logger.Debugw("add-all-port-to-routes", log.Fields{"logical-ports-count": len(lps), "device-id": device.Id})
for _, lp := range lps {
if lp.DeviceId == device.Id {
@@ -356,16 +357,16 @@
}
// isUpToDate returns true if device is up to date
-func (dr *DeviceRoutes) isUpToDate(ld *voltha.LogicalDevice) bool {
+func (dr *DeviceRoutes) isUpToDate(ldPorts map[uint32]*voltha.LogicalPort) bool {
dr.routeBuildLock.Lock()
defer dr.routeBuildLock.Unlock()
numNNI, numUNI := 0, 0
- if ld != nil {
- if len(dr.logicalPorts) != len(ld.Ports) {
+ if ldPorts != nil {
+ if len(dr.logicalPorts) != len(ldPorts) {
return false
}
numNNI = len(dr.RootPorts)
- numUNI = len(ld.Ports) - numNNI
+ numUNI = len(ldPorts) - numNNI
}
return len(dr.Routes) == numNNI*numUNI*2
}
diff --git a/rw_core/route/device_route_test.go b/rw_core/route/device_route_test.go
index fbbc802..4fe095b 100644
--- a/rw_core/route/device_route_test.go
+++ b/rw_core/route/device_route_test.go
@@ -19,15 +19,16 @@
"context"
"errors"
"fmt"
- "github.com/opencord/voltha-protos/v3/go/openflow_13"
- "github.com/opencord/voltha-protos/v3/go/voltha"
- "github.com/stretchr/testify/assert"
"math/rand"
"reflect"
"strings"
"sync"
"testing"
"time"
+
+ "github.com/opencord/voltha-protos/v3/go/openflow_13"
+ "github.com/opencord/voltha-protos/v3/go/voltha"
+ "github.com/stretchr/testify/assert"
)
const (
@@ -53,7 +54,8 @@
}
type logicalDeviceManager struct {
- logicalDevice *voltha.LogicalDevice
+ logicalDeviceID string
+ ports map[uint32]*voltha.LogicalPort
deviceRoutes *DeviceRoutes
ldChnl chan portRegistration
numLogicalPorts int
@@ -61,8 +63,14 @@
}
func newLogicalDeviceManager(ld *voltha.LogicalDevice, ch chan portRegistration, totalLogicalPorts int, done chan struct{}) *logicalDeviceManager {
+ ports := make(map[uint32]*voltha.LogicalPort)
+ for _, p := range ld.Ports {
+ ports[p.DevicePortNo] = p
+ }
+
return &logicalDeviceManager{
- logicalDevice: ld,
+ logicalDeviceID: ld.Id,
+ ports: ports,
ldChnl: ch,
numLogicalPorts: totalLogicalPorts,
done: done,
@@ -70,7 +78,7 @@
}
func (ldM *logicalDeviceManager) start(getDevice GetDeviceFunc, buildRoutes bool) {
- ldM.deviceRoutes = NewDeviceRoutes(ldM.logicalDevice.Id, getDevice)
+ ldM.deviceRoutes = NewDeviceRoutes(ldM.logicalDeviceID, getDevice)
ofpPortNo := uint32(1)
for portReg := range ldM.ldChnl {
if portReg.port == nil {
@@ -84,15 +92,14 @@
DevicePortNo: portReg.port.PortNo,
RootPort: portReg.rootPort,
}
- ldM.logicalDevice.Ports = append(ldM.logicalDevice.Ports, lp)
+ ldM.ports[lp.DevicePortNo] = lp
if buildRoutes {
device, err := getDevice(context.WithValue(context.Background(), testSetupPhase, true), lp.DeviceId)
if err != nil {
fmt.Println("Error when getting device:", lp.DeviceId, err)
}
- err = ldM.deviceRoutes.AddPort(context.Background(), lp, device, ldM.logicalDevice.Ports)
- if err != nil && !strings.Contains(err.Error(), "code = FailedPrecondition") {
- fmt.Println("(Error when adding port:", lp, len(ldM.logicalDevice.Ports), err)
+ if err := ldM.deviceRoutes.AddPort(context.Background(), lp, device, ldM.ports); err != nil && !strings.Contains(err.Error(), "code = FailedPrecondition") {
+ fmt.Println("(Error when adding port:", lp, len(ldM.ports), err)
}
}
ofpPortNo++
@@ -111,7 +118,7 @@
func newOltManager(oltDeviceID string, ldMgr *logicalDeviceManager, numNNIPort int, numPonPortOnOlt int, ch chan onuRegistration) *oltManager {
return &oltManager{
- olt: &voltha.Device{Id: oltDeviceID, ParentId: ldMgr.logicalDevice.Id, Root: true},
+ olt: &voltha.Device{Id: oltDeviceID, ParentId: ldMgr.logicalDeviceID, Root: true},
logicalDeviceMgr: ldMgr,
numNNIPort: numNNIPort,
numPonPortOnOlt: numPonPortOnOlt,
@@ -185,21 +192,21 @@
func (onuM *onuManager) start(startingOltPeerPortNo int, numPonPortOnOlt int) {
var wg sync.WaitGroup
for oltPonNo := startingOltPeerPortNo; oltPonNo < startingOltPeerPortNo+numPonPortOnOlt; oltPonNo++ {
- for i := 0; i < onuM.numOnus; i++ {
+ for onuID := 0; onuID < onuM.numOnus; onuID++ {
wg.Add(1)
- go func(idx int, oltPonNum int) {
+ go func(onuID int, oltPonNum int) {
var onu *voltha.Device
defer wg.Done()
- id := fmt.Sprintf("%d-onu-%d", oltPonNum, idx)
+ id := fmt.Sprintf("%d-onu-%d", oltPonNum, onuID)
onu = &voltha.Device{Id: id, ParentId: onuM.oltMgr.olt.Id, ParentPortNo: uint32(oltPonNum)}
- ponPort := &voltha.Port{Label: fmt.Sprintf("%s:pon-%d", onu.Id, idx), PortNo: 1, DeviceId: onu.Id, Type: voltha.Port_PON_ONU}
+ ponPort := &voltha.Port{Label: fmt.Sprintf("%s:pon-%d", onu.Id, onuID), PortNo: 1, DeviceId: onu.Id, Type: voltha.Port_PON_ONU}
ponPort.Peers = make([]*voltha.Port_PeerPort, 0)
peerPort := voltha.Port_PeerPort{DeviceId: onuM.oltMgr.olt.Id, PortNo: uint32(oltPonNum)}
ponPort.Peers = append(ponPort.Peers, &peerPort)
onu.Ports = make([]*voltha.Port, 0)
onu.Ports = append(onu.Ports, ponPort)
for j := onuM.startingUniPortNo; j < onuM.numUnisPerOnu+onuM.startingUniPortNo; j++ {
- uniPort := &voltha.Port{Label: fmt.Sprintf("%s:uni-%d", onu.Id, j), PortNo: uint32(j), DeviceId: onu.Id, Type: voltha.Port_ETHERNET_UNI}
+ uniPort := &voltha.Port{Label: fmt.Sprintf("%s:uni-%d", onu.Id, j), PortNo: uint32(oltPonNum)<<12 + uint32(onuID+1)<<4 + uint32(j), DeviceId: onu.Id, Type: voltha.Port_ETHERNET_UNI}
onu.Ports = append(onu.Ports, uniPort)
}
onuM.deviceLock.Lock()
@@ -210,7 +217,7 @@
oltPonNo: uint32(oltPonNum),
onuPonNo: 1,
}
- }(i, oltPonNo)
+ }(onuID, oltPonNo)
}
}
wg.Wait()
@@ -278,17 +285,17 @@
// Computes the routes
start := time.Now()
- err := ldMgr.deviceRoutes.ComputeRoutes(context.TODO(), ldMgr.logicalDevice.Ports)
+ err := ldMgr.deviceRoutes.ComputeRoutes(context.TODO(), ldMgr.ports)
assert.Nil(t, err)
// Validate the routes are up to date
- assert.True(t, ldMgr.deviceRoutes.isUpToDate(ld))
+ assert.True(t, ldMgr.deviceRoutes.isUpToDate(ldMgr.ports))
// Validate the expected number of routes
assert.EqualValues(t, 2*numNNIPort*numPonPortOnOlt*numOnuPerOltPonPort*numUniPerOnu, len(ldMgr.deviceRoutes.Routes))
// Validate the root ports
- for _, port := range ldMgr.logicalDevice.Ports {
+ for _, port := range ldMgr.ports {
assert.Equal(t, port.RootPort, ldMgr.deviceRoutes.IsRootPort(port.OfpPort.PortNo))
}
fmt.Println(fmt.Sprintf("Total Time:%dms, Total Routes:%d NumGetDeviceInvoked:%d", time.Since(start)/time.Millisecond, len(ldMgr.deviceRoutes.Routes), onuMgr.numGetDeviceInvoked))
@@ -326,13 +333,13 @@
ldMgr.deviceRoutes.Print()
// Validate the routes are up to date
- assert.True(t, ldMgr.deviceRoutes.isUpToDate(ld))
+ assert.True(t, ldMgr.deviceRoutes.isUpToDate(ldMgr.ports))
// Validate the expected number of routes
assert.EqualValues(t, 2*numNNIPort*numPonPortOnOlt*numOnuPerOltPonPort*numUniPerOnu, len(ldMgr.deviceRoutes.Routes))
// Validate the root ports
- for _, port := range ldMgr.logicalDevice.Ports {
+ for _, port := range ldMgr.ports {
assert.Equal(t, port.RootPort, ldMgr.deviceRoutes.IsRootPort(port.OfpPort.PortNo))
}
@@ -367,7 +374,7 @@
close(oltMgrChnl1)
close(ldMgrChnl1)
- err := ldMgr1.deviceRoutes.ComputeRoutes(context.TODO(), ldMgr1.logicalDevice.Ports)
+ err := ldMgr1.deviceRoutes.ComputeRoutes(context.TODO(), ldMgr1.ports)
assert.Nil(t, err)
routesGeneratedAllAtOnce := ldMgr1.deviceRoutes.Routes