[VOL-2778] Introducing Service definition in order to support the TT workflow
Change-Id: Ib171502e8940b5d0b219620a4503f7095d376d7a
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 21b57f2..eff9c86 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -18,6 +18,7 @@
import (
"context"
+ "encoding/hex"
"fmt"
"net"
"sync"
@@ -73,7 +74,7 @@
enableContext context.Context
enableContextCancel context.CancelFunc
- OpenoltStream *openolt.Openolt_EnableIndicationServer
+ OpenoltStream openolt.Openolt_EnableIndicationServer
enablePerf bool
}
@@ -84,7 +85,7 @@
return &olt
}
-func CreateOLT(options common.BBSimYamlConfig, isMock bool) *OltDevice {
+func CreateOLT(options common.GlobalConfig, services []common.ServiceYaml, isMock bool) *OltDevice {
oltLogger.WithFields(log.Fields{
"ID": options.Olt.ID,
"NumNni": options.Olt.NniPorts,
@@ -146,44 +147,61 @@
olt.Nnis = append(olt.Nnis, &nniPort)
}
+ // Create device and Services
+
+ nextCtag := map[string]int{}
+ nextStag := map[string]int{}
+
// create PON ports
+ for i := 0; i < olt.NumPon; i++ {
+ p := CreatePonPort(&olt, uint32(i))
- if options.BBSim.STagAllocation == common.TagAllocationShared && options.BBSim.CTagAllocation == common.TagAllocationShared {
- oltLogger.Fatalf("This configuration will result in duplicate C/S tags combination")
- } else if options.BBSim.STagAllocation == common.TagAllocationUnique && options.BBSim.CTagAllocation == common.TagAllocationUnique {
- oltLogger.Fatalf("This configuration is not supported yet")
- } else if options.BBSim.STagAllocation == common.TagAllocationShared && options.BBSim.CTagAllocation == common.TagAllocationUnique {
- // ATT case
- availableCTag := options.BBSim.CTag
- for i := 0; i < olt.NumPon; i++ {
- p := CreatePonPort(&olt, uint32(i))
+ // create ONU devices
+ for j := 0; j < olt.NumOnuPerPon; j++ {
+ delay := time.Duration(olt.Delay*j) * time.Millisecond
+ o := CreateONU(&olt, p, uint32(j+1), delay, isMock)
- // create ONU devices
- for j := 0; j < olt.NumOnuPerPon; j++ {
- delay := time.Duration(olt.Delay*j) * time.Millisecond
- o := CreateONU(&olt, p, uint32(j+1), options.BBSim.STag, availableCTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
- p.Onus = append(p.Onus, o)
- availableCTag = availableCTag + 1
+ for k, s := range common.Services {
+
+ // find the correct cTag for this service
+ if _, ok := nextCtag[s.Name]; !ok {
+ // it's the first time we iterate over this service,
+ // so we start from the config value
+ nextCtag[s.Name] = s.CTag
+ } else {
+ // we have a previous value, so we check it
+ // if Allocation is unique, we increment,
+ // otherwise (shared) we do nothing
+ if s.CTagAllocation == common.TagAllocationUnique.String() {
+ nextCtag[s.Name] = nextCtag[s.Name] + 1
+ }
+ }
+
+ // find the correct sTag for this service
+ if _, ok := nextStag[s.Name]; !ok {
+ nextStag[s.Name] = s.STag
+ } else {
+ if s.STagAllocation == common.TagAllocationUnique.String() {
+ nextStag[s.Name] = nextStag[s.Name] + 1
+ }
+ }
+
+ mac := net.HardwareAddr{0x2e, 0x60, byte(olt.ID), byte(p.ID), byte(o.ID), byte(k)}
+ service, err := NewService(s.Name, mac, o, nextCtag[s.Name], nextStag[s.Name],
+ s.NeedsEapol, s.NeedsDchp, s.NeedsIgmp, s.TechnologyProfileID, s.UniTagMatch,
+ s.ConfigureMacAddress, s.UsPonCTagPriority, s.UsPonSTagPriority, s.DsPonCTagPriority, s.DsPonSTagPriority)
+
+ if err != nil {
+ oltLogger.WithFields(log.Fields{
+ "Err": err.Error(),
+ }).Fatal("Can't create Service")
+ }
+
+ o.Services = append(o.Services, service)
}
-
- olt.Pons = append(olt.Pons, p)
+ p.Onus = append(p.Onus, o)
}
- } else if options.BBSim.STagAllocation == common.TagAllocationUnique && options.BBSim.CTagAllocation == common.TagAllocationShared {
- // DT case
- availableSTag := options.BBSim.STag
- for i := 0; i < olt.NumPon; i++ {
- p := CreatePonPort(&olt, uint32(i))
-
- // create ONU devices
- for j := 0; j < olt.NumOnuPerPon; j++ {
- delay := time.Duration(olt.Delay*j) * time.Millisecond
- o := CreateONU(&olt, p, uint32(j+1), availableSTag, options.BBSim.CTag, options.BBSim.EnableAuth, options.BBSim.EnableDhcp, delay, isMock)
- p.Onus = append(p.Onus, o)
- availableSTag = availableSTag + 1
- }
-
- olt.Pons = append(olt.Pons, p)
- }
+ olt.Pons = append(olt.Pons, p)
}
if !isMock {
@@ -238,7 +256,7 @@
func (o *OltDevice) RestartOLT() error {
- rebootDelay := common.Options.Olt.OltRebootDelay
+ rebootDelay := common.Config.Olt.OltRebootDelay
oltLogger.WithFields(log.Fields{
"oltId": o.ID,
@@ -298,7 +316,7 @@
// newOltServer launches a new grpc server for OpenOLT
func (o *OltDevice) newOltServer() (*grpc.Server, error) {
- address := common.Options.BBSim.OpenOltAddress
+ address := common.Config.BBSim.OpenOltAddress
lis, err := net.Listen("tcp", address)
if err != nil {
oltLogger.Fatalf("OLT failed to listen: %v", err)
@@ -351,7 +369,7 @@
wg := sync.WaitGroup{}
wg.Add(3)
- o.OpenoltStream = &stream
+ o.OpenoltStream = stream
// create Go routine to process all OLT events
go o.processOltMessages(o.enableContext, stream, &wg)
@@ -444,7 +462,7 @@
"messageType": message.Type,
"OnuId": message.Data.OnuId,
"IntfId": message.Data.IntfId,
- }).Info("Received message on OMCI Sim channel")
+ }).Debug("Received message on OMCI Sim channel")
onuId := message.Data.OnuId
intfId := message.Data.IntfId
@@ -577,7 +595,7 @@
func (o *OltDevice) sendPonIndication(ponPortID uint32) {
- stream := *o.OpenoltStream
+ stream := o.OpenoltStream
pon, _ := o.GetPonById(ponPortID)
// Send IntfIndication for PON port
discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
@@ -624,7 +642,7 @@
data := &openolt.Indication_PortStats{
PortStats: stats,
}
- stream := *o.OpenoltStream
+ stream := o.OpenoltStream
if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
oltLogger.Errorf("Failed to send PortStats: %v", err)
return
@@ -743,7 +761,7 @@
return
}
- onu, err := o.FindOnuByMacAddress(onuMac)
+ s, err := o.FindServiceByMacAddress(onuMac)
if err != nil {
log.WithFields(log.Fields{
"IntfType": "nni",
@@ -754,7 +772,9 @@
return
}
- doubleTaggedPkt, err := packetHandlers.PushDoubleTag(onu.STag, onu.CTag, message.Pkt)
+ service := s.(*Service)
+
+ doubleTaggedPkt, err := packetHandlers.PushDoubleTag(service.STag, service.CTag, message.Pkt)
if err != nil {
log.Error("Fail to add double tag to packet")
}
@@ -773,9 +793,9 @@
oltLogger.WithFields(log.Fields{
"IntfType": data.PktInd.IntfType,
"IntfId": nniId,
- "Pkt": doubleTaggedPkt.Data(),
- "OnuSn": onu.Sn(),
- }).Tracef("Sent PktInd indication")
+ "Pkt": hex.EncodeToString(doubleTaggedPkt.Data()),
+ "OnuSn": service.Onu.Sn(),
+ }).Trace("Sent PktInd indication (from NNI to VOLTHA)")
}
}
wg.Done()
@@ -815,19 +835,20 @@
return &Onu{}, fmt.Errorf("cannot-find-onu-by-id-%v-%v", intfId, onuId)
}
-// returns an ONU with a given Mac Address
-func (o *OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
+// returns a Service with a given Mac Address
+func (o *OltDevice) FindServiceByMacAddress(mac net.HardwareAddr) (ServiceIf, error) {
// TODO this function can be a performance bottleneck when we have many ONUs,
// memoizing it will remove the bottleneck
for _, pon := range o.Pons {
for _, onu := range pon.Onus {
- if onu.HwAddress.String() == mac.String() {
- return onu, nil
+ s, err := onu.findServiceByMacAddress(mac)
+ if err == nil {
+ return s, nil
}
}
}
- return &Onu{}, fmt.Errorf("cannot-find-onu-by-mac-address-%s", mac)
+ return nil, fmt.Errorf("cannot-find-service-by-mac-address-%s", mac)
}
// GRPC Endpoints
@@ -963,7 +984,7 @@
OnuID: onu.ID,
OnuSN: onu.SerialNumber,
}
- onu.sendOnuIndication(onuIndication, *o.OpenoltStream)
+ onu.sendOnuIndication(onuIndication, o.OpenoltStream)
}
@@ -999,7 +1020,7 @@
OnuID: onu.ID,
OnuSN: onu.SerialNumber,
}
- onu.sendOnuIndication(onuIndication, *o.OpenoltStream)
+ onu.sendOnuIndication(onuIndication, o.OpenoltStream)
}
@@ -1174,11 +1195,11 @@
"PonPorts": o.NumPon,
}).Info("OLT receives GetDeviceInfo call from VOLTHA")
devinfo := new(openolt.DeviceInfo)
- devinfo.Vendor = common.Options.Olt.Vendor
- devinfo.Model = common.Options.Olt.Model
- devinfo.HardwareVersion = common.Options.Olt.HardwareVersion
- devinfo.FirmwareVersion = common.Options.Olt.FirmwareVersion
- devinfo.Technology = common.Options.Olt.Technology
+ devinfo.Vendor = common.Config.Olt.Vendor
+ devinfo.Model = common.Config.Olt.Model
+ devinfo.HardwareVersion = common.Config.Olt.HardwareVersion
+ devinfo.FirmwareVersion = common.Config.Olt.FirmwareVersion
+ devinfo.Technology = common.Config.Olt.Technology
devinfo.PonPorts = uint32(o.NumPon)
devinfo.OnuIdStart = 1
devinfo.OnuIdEnd = 255
@@ -1189,7 +1210,7 @@
devinfo.FlowIdStart = 1
devinfo.FlowIdEnd = 16383
devinfo.DeviceSerialNumber = o.SerialNumber
- devinfo.DeviceId = common.Options.Olt.DeviceId
+ devinfo.DeviceId = common.Config.Olt.DeviceId
return devinfo, nil
}
@@ -1254,20 +1275,34 @@
"IntfId": onu.PonPortID,
"OnuId": onu.ID,
"OnuSn": onu.Sn(),
- }).Tracef("Received OnuPacketOut")
+ }).Info("Received OnuPacketOut")
rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
pktType, _ := packetHandlers.IsEapolOrDhcp(rawpkt)
+ pktMac, err := packetHandlers.GetDstMacAddressFromPacket(rawpkt)
+
+ if err != nil {
+ log.WithFields(log.Fields{
+ "IntfId": onu.PonPortID,
+ "OnuId": onu.ID,
+ "OnuSn": onu.Sn(),
+ "Pkt": rawpkt.Data(),
+ }).Error("Can't find Dst MacAddress in packet, droppint it")
+ return new(openolt.Empty), nil
+ }
+
msg := Message{
Type: OnuPacketOut,
Data: OnuPacketMessage{
- IntfId: onuPkt.IntfId,
- OnuId: onuPkt.OnuId,
- Packet: rawpkt,
- Type: pktType,
+ IntfId: onuPkt.IntfId,
+ OnuId: onuPkt.OnuId,
+ Packet: rawpkt,
+ Type: pktType,
+ MacAddress: pktMac,
},
}
+
onu.Channel <- msg
return new(openolt.Empty), nil