[SEBA-817][SEBA-821]
Adding c/s tags and hw address in the onu struct
DHCP State machine completed
Cleaned up logs
Change-Id: Iadb1d3967befe1c402e302a552b67faa2701f5c5
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 6ce09a1..c75f2d1 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -20,10 +20,10 @@
"context"
"errors"
"fmt"
- bbsim "github.com/opencord/bbsim/internal/bbsim/types"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/looplab/fsm"
+ bbsim "github.com/opencord/bbsim/internal/bbsim/types"
"github.com/opencord/voltha-protos/go/openolt"
"github.com/opencord/voltha-protos/go/tech_profile"
log "github.com/sirupsen/logrus"
@@ -43,32 +43,33 @@
var olt = OltDevice{}
-func GetOLT() OltDevice {
+func GetOLT() OltDevice {
return olt
}
-func CreateOLT(seq int, nni int, pon int, onuPerPon int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, group *sync.WaitGroup) OltDevice {
+func CreateOLT(seq int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, group *sync.WaitGroup) OltDevice {
oltLogger.WithFields(log.Fields{
- "ID": seq,
- "NumNni":nni,
- "NumPon":pon,
- "NumOnuPerPon":onuPerPon,
+ "ID": seq,
+ "NumNni": nni,
+ "NumPon": pon,
+ "NumOnuPerPon": onuPerPon,
}).Debug("CreateOLT")
olt = OltDevice{
- ID: seq,
+ ID: seq,
SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", seq),
OperState: getOperStateFSM(func(e *fsm.Event) {
oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
}),
- NumNni:nni,
- NumPon:pon,
- NumOnuPerPon:onuPerPon,
- Pons: []PonPort{},
- Nnis: []NniPort{},
- channel: make(chan Message),
- oltDoneChannel: oltDoneChannel,
- apiDoneChannel: apiDoneChannel,
+ NumNni: nni,
+ NumPon: pon,
+ NumOnuPerPon: onuPerPon,
+ Pons: []PonPort{},
+ Nnis: []NniPort{},
+ channel: make(chan Message),
+ oltDoneChannel: oltDoneChannel,
+ apiDoneChannel: apiDoneChannel,
+ nniPktInChannel: make(chan *bbsim.PacketMsg, 1024), // packets coming in from the NNI and going to VOLTHA
}
// OLT State machine
@@ -87,22 +88,21 @@
)
// create NNI Port
- nniPort := NniPort{
- ID: uint32(0),
- OperState: getOperStateFSM(func(e *fsm.Event) {
- oltLogger.Debugf("Changing NNI OperState from %s to %s", e.Src, e.Dst)
- }),
- Type: "nni",
+ nniPort, err := CreateNNI(&olt)
+
+ if err != nil {
+ oltLogger.Fatalf("Couldn't create NNI Port: %v", err)
}
+
olt.Nnis = append(olt.Nnis, nniPort)
// create PON ports
- //onuId := 1
+ availableCTag := cTagInit
for i := 0; i < pon; i++ {
p := PonPort{
NumOnu: olt.NumOnuPerPon,
- ID: uint32(i),
- Type: "pon",
+ ID: uint32(i),
+ Type: "pon",
}
p.OperState = getOperStateFSM(func(e *fsm.Event) {
oltLogger.WithFields(log.Fields{
@@ -113,9 +113,9 @@
// create ONU devices
for j := 0; j < onuPerPon; j++ {
//o := CreateONU(olt, p, uint32(onuId))
- o := CreateONU(olt, p, uint32(j + 1))
+ o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag)
p.Onus = append(p.Onus, o)
- //onuId = onuId + 1
+ availableCTag = availableCTag + 1
}
olt.Pons = append(olt.Pons, p)
@@ -129,7 +129,7 @@
func newOltServer(o OltDevice) error {
// TODO make configurable
- address := "0.0.0.0:50060"
+ address := "0.0.0.0:50060"
lis, err := net.Listen("tcp", address)
if err != nil {
oltLogger.Fatalf("OLT failed to listen: %v", err)
@@ -144,7 +144,7 @@
oltLogger.Debugf("OLT Listening on: %v", address)
for {
- _, ok := <- *o.oltDoneChannel
+ _, ok := <-*o.oltDoneChannel
if !ok {
// if the olt channel is closed, stop the gRPC server
log.Warnf("Stopping OLT gRPC server")
@@ -161,15 +161,16 @@
// Device Methods
-func (o OltDevice) Enable (stream openolt.Openolt_EnableIndicationServer) error {
+func (o OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
oltLogger.Debug("Enable OLT called")
wg := sync.WaitGroup{}
- wg.Add(1)
+ wg.Add(2)
// create a channel for all the OLT events
go o.processOltMessages(stream)
+ go o.processNniPacketIns(stream)
// enable the OLT
olt_msg := Message{
@@ -207,9 +208,9 @@
go onu.processOnuMessages(stream)
go onu.processOmciMessages(stream)
msg := Message{
- Type: OnuDiscIndication,
+ Type: OnuDiscIndication,
Data: OnuDiscIndicationMessage{
- Onu: onu,
+ Onu: onu,
OperState: UP,
},
}
@@ -257,8 +258,8 @@
nni.OperState.Event("enable")
// NOTE Operstate may need to be an integer
operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
- Type: nni.Type,
- IntfId: nni.ID,
+ Type: nni.Type,
+ IntfId: nni.ID,
OperState: nni.OperState.Current(),
}}
@@ -267,8 +268,8 @@
}
oltLogger.WithFields(log.Fields{
- "Type": nni.Type,
- "IntfId": nni.ID,
+ "Type": nni.Type,
+ "IntfId": nni.ID,
"OperState": nni.OperState.Current(),
}).Debug("Sent Indication_IntfOperInd for NNI")
}
@@ -277,7 +278,7 @@
pon, _ := o.getPonById(msg.PonPortID)
pon.OperState.Event("enable")
discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
- IntfId: pon.ID,
+ IntfId: pon.ID,
OperState: pon.OperState.Current(),
}}
@@ -286,13 +287,13 @@
}
oltLogger.WithFields(log.Fields{
- "IntfId": pon.ID,
+ "IntfId": pon.ID,
"OperState": pon.OperState.Current(),
}).Debug("Sent Indication_IntfInd")
operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
- Type: pon.Type,
- IntfId: pon.ID,
+ Type: pon.Type,
+ IntfId: pon.ID,
OperState: pon.OperState.Current(),
}}
@@ -301,8 +302,8 @@
}
oltLogger.WithFields(log.Fields{
- "Type": pon.Type,
- "IntfId": pon.ID,
+ "Type": pon.Type,
+ "IntfId": pon.ID,
"OperState": pon.OperState.Current(),
}).Debug("Sent Indication_IntfOperInd for PON")
}
@@ -311,9 +312,8 @@
oltLogger.Debug("Started OLT Indication Channel")
for message := range o.channel {
-
oltLogger.WithFields(log.Fields{
- "oltId": o.ID,
+ "oltId": o.ID,
"messageType": message.Type,
}).Trace("Received message")
@@ -341,11 +341,32 @@
}
}
+func (o OltDevice) processNniPacketIns(stream openolt.Openolt_EnableIndicationServer) {
+ oltLogger.WithFields(log.Fields{
+ "nniChannel": o.nniPktInChannel,
+ }).Debug("Started NNI Channel")
+ nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
+ for message := range o.nniPktInChannel {
+ oltLogger.Debug("Received packets on NNI Channel")
+ data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
+ IntfType: "nni",
+ IntfId: nniId,
+ Pkt: message.Pkt.Data()}}
+ if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+ oltLogger.WithFields(log.Fields{
+ "IntfType": data.PktInd.IntfType,
+ "IntfId": nniId,
+ "Pkt": message.Pkt.Data(),
+ }).Errorf("Fail to send PktInd indication: %v", err)
+ }
+ }
+}
+
// GRPC Endpoints
-func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
+func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
oltLogger.WithFields(log.Fields{
- "onuSerialNumber": onu.SerialNumber,
+ "OnuSn": onuSnToString(onu.SerialNumber),
}).Info("Received ActivateOnu call from VOLTHA")
pon, _ := o.getPonById(onu.IntfId)
@@ -353,28 +374,28 @@
// NOTE we need to immediately activate the ONU or the OMCI state machine won't start
msg := Message{
- Type: OnuIndication,
- Data: OnuIndicationMessage{
+ Type: OnuIndication,
+ Data: OnuIndicationMessage{
OnuSN: onu.SerialNumber,
PonPortID: onu.IntfId,
OperState: UP,
},
}
_onu.channel <- msg
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
+func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
oltLogger.Error("DeactivateOnu not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
+func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
oltLogger.Error("DeleteOnu not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
+func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
// NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
olt_msg := Message{
Type: OltIndication,
@@ -383,37 +404,37 @@
},
}
o.channel <- olt_msg
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
+func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
oltLogger.Error("DisablePonIf not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
+func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
o.Enable(stream)
return nil
}
-func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
+func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
oltLogger.Error("EnablePonIf not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
+func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
oltLogger.WithFields(log.Fields{
- "IntfId": flow.AccessIntfId,
- "OnuId": flow.OnuId,
- "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
+ "IntfId": flow.AccessIntfId,
+ "OnuId": flow.OnuId,
+ "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
"InnerVlan": flow.Classifier.IVid,
"OuterVlan": flow.Classifier.OVid,
- "FlowType": flow.FlowType,
- "FlowId": flow.FlowId,
- "UniID": flow.UniId,
- "PortNo": flow.PortNo,
- }).Infof("OLT receives Flow")
+ "FlowType": flow.FlowType,
+ "FlowId": flow.FlowId,
+ "UniID": flow.UniId,
+ "PortNo": flow.PortNo,
+ }).Tracef("OLT receives Flow")
// TODO optionally store flows somewhere
if flow.AccessIntfId == -1 {
@@ -425,34 +446,34 @@
onu, _ := pon.getOnuById(uint32(flow.OnuId))
msg := Message{
- Type: FlowUpdate,
- Data: OnuFlowUpdateMessage{
- PonPortID: pon.ID,
- OnuID: onu.ID,
- Flow: flow,
+ Type: FlowUpdate,
+ Data: OnuFlowUpdateMessage{
+ PonPortID: pon.ID,
+ OnuID: onu.ID,
+ Flow: flow,
},
}
onu.channel <- msg
}
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
- oltLogger.Info("received FlowRemove")
+func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
+ oltLogger.Tracef("received FlowRemove")
// TODO store flows somewhere
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
+func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
oltLogger.Error("HeartbeatCheck not implemented")
- return new(openolt.Heartbeat) , nil
+ return new(openolt.Heartbeat), nil
}
-func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
+func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
oltLogger.WithFields(log.Fields{
- "oltId": o.ID,
+ "oltId": o.ID,
"PonPorts": o.NumPon,
}).Info("OLT receives GetDeviceInfo call from VOLTHA")
devinfo := new(openolt.DeviceInfo)
@@ -475,67 +496,76 @@
return devinfo, nil
}
-func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
+func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
pon, _ := o.getPonById(omci_msg.IntfId)
onu, _ := pon.getOnuById(omci_msg.OnuId)
msg := Message{
- Type: OMCI,
- Data: OmciMessage{
- OnuSN: onu.SerialNumber,
- OnuID: onu.ID,
- omciMsg: omci_msg,
+ Type: OMCI,
+ Data: OmciMessage{
+ OnuSN: onu.SerialNumber,
+ OnuID: onu.ID,
+ omciMsg: omci_msg,
},
}
onu.channel <- msg
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
+func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
pon, _ := o.getPonById(onuPkt.IntfId)
onu, _ := pon.getOnuById(onuPkt.OnuId)
rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
- // NOTE is this the best way to the to the ethertype?
etherType := rawpkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet).EthernetType
if etherType == layers.EthernetTypeEAPOL {
eapolPkt := bbsim.ByteMsg{IntfId: onuPkt.IntfId, OnuId: onuPkt.OnuId, Bytes: rawpkt.Data()}
onu.eapolPktOutCh <- &eapolPkt
+ } else if layerDHCP := rawpkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
+ // TODO use IsDhcpPacket
+ // TODO we need to untag the packets
+ // NOTE here we receive packets going from the DHCP Server to the ONU
+ // for now we expect them to be double-tagged, but ideally the should be single tagged
+ dhcpPkt := bbsim.ByteMsg{IntfId: onuPkt.IntfId, OnuId: onuPkt.OnuId, Bytes: rawpkt.Data()}
+ onu.dhcpPktOutCh <- &dhcpPkt
}
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
-func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
+func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
oltLogger.Info("Shutting Down")
close(*o.oltDoneChannel)
close(*o.apiDoneChannel)
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
oltLogger.Error("ReenableOlt not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
- oltLogger.Warn("UplinkPacketOut not implemented")
- return new(openolt.Empty) , nil
+ pkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
+
+ sendNniPacket(pkt)
+ // NOTE should we return an error if sendNniPakcet fails?
+ return new(openolt.Empty), nil
}
-func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
+func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
oltLogger.Error("CollectStatistics not implemented")
- return new(openolt.Empty) , nil
+ return new(openolt.Empty), nil
}
func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
oltLogger.Error("GetOnuInfo not implemented")
- return new(openolt.OnuIndication) , nil
+ return new(openolt.OnuIndication), nil
}
func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
oltLogger.Error("GetPonIf not implemented")
- return new(openolt.IntfIndication) , nil
+ return new(openolt.IntfIndication), nil
}
func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
@@ -556,4 +586,4 @@
func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
oltLogger.Info("received RemoveTrafficSchedulers")
return new(openolt.Empty), nil
-}
\ No newline at end of file
+}