Merge "[VOL-2351] Sending the same indications as a real OLT on disable"
diff --git a/internal/bbsim/devices/nni.go b/internal/bbsim/devices/nni.go
index 6e5e34d..0d658e9 100644
--- a/internal/bbsim/devices/nni.go
+++ b/internal/bbsim/devices/nni.go
@@ -153,12 +153,12 @@
}
// NewVethChan returns a new channel for receiving packets over the NNI interface
-func (n *NniPort) NewVethChan() (chan *types.PacketMsg, error) {
- ch, err := listenOnVeth(n.nniVeth)
+func (n *NniPort) NewVethChan() (chan *types.PacketMsg, *pcap.Handle, error) {
+ ch, handle, err := listenOnVeth(n.nniVeth)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- return ch, err
+ return ch, handle, err
}
// setVethUp is responsible to activate a virtual interface
@@ -211,16 +211,17 @@
return handle, nil
}
-var listenOnVeth = func(vethName string) (chan *types.PacketMsg, error) {
+var listenOnVeth = func(vethName string) (chan *types.PacketMsg, *pcap.Handle, error) {
handle, err := getVethHandler(vethName)
if err != nil {
- return nil, err
+ return nil, nil, err
}
channel := make(chan *types.PacketMsg, 1024)
go func() {
+ nniLogger.Info("Start listening on NNI for packets")
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
@@ -237,7 +238,8 @@
}
channel <- &pkt
}
+ nniLogger.Info("Stop listening on NNI for packets")
}()
- return channel, nil
+ return channel, handle, nil
}
diff --git a/internal/bbsim/devices/nni_test.go b/internal/bbsim/devices/nni_test.go
index 348d40f..9ee945e 100644
--- a/internal/bbsim/devices/nni_test.go
+++ b/internal/bbsim/devices/nni_test.go
@@ -19,6 +19,7 @@
import (
"errors"
+ "github.com/google/gopacket/pcap"
"testing"
"github.com/opencord/bbsim/internal/bbsim/types"
@@ -58,9 +59,9 @@
listenOnVethCalled := false
_listenOnVeth := listenOnVeth
defer func() { listenOnVeth = _listenOnVeth }()
- listenOnVeth = func(vethName string) (chan *types.PacketMsg, error) {
+ listenOnVeth = func(vethName string) (chan *types.PacketMsg, *pcap.Handle, error) {
listenOnVethCalled = true
- return make(chan *types.PacketMsg, 1), nil
+ return make(chan *types.PacketMsg, 1), nil, nil
}
spy := &ExecutorSpy{
failRun: false,
@@ -71,7 +72,7 @@
nni := NniPort{}
err := createNNIPair(spy, &olt, &nni)
- olt.nniPktInChannel, _ = nni.NewVethChan()
+ olt.nniPktInChannel, olt.nniHandle, _ = nni.NewVethChan()
assert.Equal(t, spy.CommandCallCount, 3)
assert.Equal(t, startDHCPServerCalled, true)
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index cc4965c..1ccb5be 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -20,6 +20,7 @@
"context"
"errors"
"fmt"
+ "github.com/google/gopacket/pcap"
"net"
"sync"
"time"
@@ -54,6 +55,7 @@
InternalState *fsm.FSM
channel chan Message
nniPktInChannel chan *bbsim.PacketMsg // packets coming in from the NNI and going to VOLTHA
+ nniHandle *pcap.Handle // handle on the NNI interface, close it when shutting down the NNI channel
Delay int
@@ -175,18 +177,28 @@
o.nniPktInChannel = make(chan *bbsim.PacketMsg, 1024)
// FIXME we are assuming we have only one NNI
if o.Nnis[0] != nil {
- ch, err := o.Nnis[0].NewVethChan()
+ // NOTE we want to make sure the state is down when we initialize the OLT,
+ // the NNI may be in a bad state after a disable/reboot as we are not disabling it for
+ // in-band management
+ o.Nnis[0].OperState.SetState("down")
+ ch, handle, err := o.Nnis[0].NewVethChan()
if err == nil {
+ oltLogger.WithFields(log.Fields{
+ "Type": o.Nnis[0].Type,
+ "IntfId": o.Nnis[0].ID,
+ "OperState": o.Nnis[0].OperState.Current(),
+ }).Info("NNI Channel created")
o.nniPktInChannel = ch
+ o.nniHandle = handle
} else {
- log.Errorf("Error getting NNI channel: %v", err)
+ oltLogger.Errorf("Error getting NNI channel: %v", err)
}
}
for i := range olt.Pons {
for _, onu := range olt.Pons[i].Onus {
if err := onu.InternalState.Event("initialize"); err != nil {
- log.Errorf("Error initializing ONU: %v", err)
+ oltLogger.Errorf("Error initializing ONU: %v", err)
return err
}
}
@@ -220,8 +232,16 @@
// terminate the OLT's processOltMessages go routine
close(o.channel)
// terminate the OLT's processNniPacketIns go routine
+ o.nniHandle.Close()
close(o.nniPktInChannel)
+ for i := range olt.Pons {
+ for _, onu := range olt.Pons[i].Onus {
+ // NOTE while the olt is off, restore the ONU to the initial state
+ onu.InternalState.SetState("created")
+ }
+ }
+
time.Sleep(time.Duration(rebootDelay) * time.Second)
if err := o.InternalState.Event("initialize"); err != nil {
@@ -408,7 +428,23 @@
func (o *OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
nni, _ := o.getNniById(msg.NniPortID)
- nni.OperState.Event("enable")
+ if msg.OperState == UP {
+ if err := nni.OperState.Event("enable"); err != nil {
+ log.WithFields(log.Fields{
+ "Type": nni.Type,
+ "IntfId": nni.ID,
+ "OperState": nni.OperState.Current(),
+ }).Errorf("Can't move NNI Port to enabled state: %v", err)
+ }
+ } else if msg.OperState == DOWN {
+ if err := nni.OperState.Event("disable"); err != nil {
+ log.WithFields(log.Fields{
+ "Type": nni.Type,
+ "IntfId": nni.ID,
+ "OperState": nni.OperState.Current(),
+ }).Errorf("Can't move NNI Port to disable state: %v", err)
+ }
+ }
// NOTE Operstate may need to be an integer
operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Type: nni.Type,
@@ -430,7 +466,23 @@
func (o *OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
pon, _ := o.GetPonById(msg.PonPortID)
- pon.OperState.Event("enable")
+ if msg.OperState == UP {
+ if err := pon.OperState.Event("enable"); err != nil {
+ log.WithFields(log.Fields{
+ "Type": pon.Type,
+ "IntfId": pon.ID,
+ "OperState": pon.OperState.Current(),
+ }).Errorf("Can't move PON Port to enable state: %v", err)
+ }
+ } else if msg.OperState == DOWN {
+ if err := pon.OperState.Event("disable"); err != nil {
+ log.WithFields(log.Fields{
+ "Type": pon.Type,
+ "IntfId": pon.ID,
+ "OperState": pon.OperState.Current(),
+ }).Errorf("Can't move PON Port to disable state: %v", err)
+ }
+ }
discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
IntfId: pon.ID,
OperState: pon.OperState.Current(),
@@ -516,7 +568,7 @@
func (o *OltDevice) processNniPacketIns(ctx context.Context, stream openolt.Openolt_EnableIndicationServer, wg *sync.WaitGroup) {
oltLogger.WithFields(log.Fields{
"nniChannel": o.nniPktInChannel,
- }).Debug("Started NNI Channel")
+ }).Debug("Started Processing Packets arriving from the NNI")
nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
ch := o.nniPktInChannel
@@ -679,18 +731,7 @@
"oltId": o.ID,
}).Info("Disabling OLT")
- for i, pon := range o.Pons {
- // disable all onus
- for _, onu := range o.Pons[i].Onus {
- // NOTE order of these is important.
- if err := onu.OperState.Event("disable"); err != nil {
- log.Errorf("Error disabling ONU oper state: %v", err)
- }
- if err := onu.InternalState.Event("disable"); err != nil {
- log.Errorf("Error disabling ONU: %v", err)
- }
- }
-
+ for _, pon := range o.Pons {
// disable PONs
msg := Message{
Type: PonIndication,
@@ -703,17 +744,8 @@
o.channel <- msg
}
- // disable NNI
- for _, nni := range o.Nnis {
- msg := Message{
- Type: NniIndication,
- Data: NniIndicationMessage{
- OperState: DOWN,
- NniPortID: nni.ID,
- },
- }
- o.channel <- msg
- }
+ // Note that we are not disabling the NNI as the real OLT does not.
+ // The reason for that is in-band management
// disable OLT
oltMsg := Message{