[VOL-3279] Resetting the GemPort when all the flows in an ONU are removed
Change-Id: Icd01703900cd14e0e3baf2abb4669524a47dbeeb
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 78569f5..1acb063 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -26,7 +26,7 @@
"github.com/cboling/omci"
"github.com/google/gopacket/layers"
- backoff "github.com/jpillora/backoff"
+ "github.com/jpillora/backoff"
"github.com/looplab/fsm"
"github.com/opencord/bbsim/internal/bbsim/packetHandlers"
"github.com/opencord/bbsim/internal/bbsim/responders/dhcp"
@@ -52,7 +52,7 @@
type Onu struct {
ID uint32
PonPortID uint32
- PonPort PonPort
+ PonPort *PonPort
STag int
CTag int
Auth bool // automatically start EAPOL if set to true
@@ -71,6 +71,7 @@
EapolFlowReceived bool
DhcpFlowReceived bool
Flows []FlowKey
+ FlowIds []uint32 // keep track of the flows we currently have in the ONU
OperState *fsm.FSM
SerialNumber *openolt.SerialNumber
@@ -79,10 +80,9 @@
GemPortChannels []chan bool // this channels are used to notify everyone that is interested that a GemPort has been added
// OMCI params
- tid uint16
- hpTid uint16
- seqNumber uint16
- HasGemPort bool
+ tid uint16
+ hpTid uint16
+ seqNumber uint16
DoneChannel chan bool // this channel is used to signal once the onu is complete (when the struct is used by BBR)
TrafficSchedulers *tech_profile.TrafficSchedulers
@@ -98,10 +98,10 @@
return listener
}
-func CreateONU(olt *OltDevice, pon PonPort, id uint32, sTag int, cTag int, auth bool, dhcp bool, delay time.Duration, isMock bool) *Onu {
+func CreateONU(olt *OltDevice, pon *PonPort, id uint32, sTag int, cTag int, auth bool, dhcp bool, delay time.Duration, isMock bool) *Onu {
b := &backoff.Backoff{
//These are the defaults
- Min: 1 * time.Second,
+ Min: 5 * time.Second,
Max: 35 * time.Second,
Factor: 1.5,
Jitter: false,
@@ -401,9 +401,12 @@
case OMCI:
msg, _ := message.Data.(OmciMessage)
o.handleOmciMessage(msg, stream)
- case FlowUpdate:
+ case FlowAdd:
msg, _ := message.Data.(OnuFlowUpdateMessage)
- o.handleFlowUpdate(msg)
+ o.handleFlowAdd(msg)
+ case FlowRemoved:
+ msg, _ := message.Data.(OnuFlowUpdateMessage)
+ o.handleFlowRemove(msg)
case StartEAPOL:
o.handleEAPOLStart(stream)
case StartDHCP:
@@ -751,7 +754,7 @@
o.ID = id
}
-func (o *Onu) handleFlowUpdate(msg OnuFlowUpdateMessage) {
+func (o *Onu) handleFlowAdd(msg OnuFlowUpdateMessage) {
onuLogger.WithFields(log.Fields{
"DstPort": msg.Flow.Classifier.DstPort,
"EthType": fmt.Sprintf("%x", msg.Flow.Classifier.EthType),
@@ -768,7 +771,7 @@
"SrcPort": msg.Flow.Classifier.SrcPort,
"UniID": msg.Flow.UniId,
"ClassifierOPbits": msg.Flow.Classifier.OPbits,
- }).Debug("ONU receives Flow")
+ }).Debug("ONU receives FlowAdd")
if msg.Flow.UniId != 0 {
// as of now BBSim only support a single UNI, so ignore everything that is not targeted to it
@@ -780,6 +783,8 @@
return
}
+ o.FlowIds = append(o.FlowIds, msg.Flow.FlowId)
+
if msg.Flow.Classifier.EthType == uint32(layers.EthernetTypeEAPOL) && msg.Flow.Classifier.OVid == 4091 {
// NOTE storing the PortNO, it's needed when sending PacketIndications
o.storePortNumber(uint32(msg.Flow.PortNo))
@@ -860,6 +865,38 @@
}
}
+func (o *Onu) handleFlowRemove(msg OnuFlowUpdateMessage) {
+ onuLogger.WithFields(log.Fields{
+ "IntfId": o.PonPortID,
+ "OnuId": o.ID,
+ "SerialNumber": o.Sn(),
+ "FlowId": msg.Flow.FlowId,
+ "FlowType": msg.Flow.FlowType,
+ }).Debug("ONU receives FlowRemove")
+
+ for idx, flow := range o.FlowIds {
+ // If the gemport is found, delete it from local cache.
+ if flow == msg.Flow.FlowId {
+ o.FlowIds = append(o.FlowIds[:idx], o.FlowIds[idx+1:]...)
+ break
+ }
+ }
+
+ if len(o.FlowIds) == 0 {
+ onuLogger.WithFields(log.Fields{
+ "IntfId": o.PonPortID,
+ "OnuId": o.ID,
+ "SerialNumber": o.Sn(),
+ }).Info("Resetting GemPort")
+ o.GemPortAdded = false
+
+ // TODO ideally we should keep track of the flow type (and not only the ID)
+ // so that we can properly set these two flag when the flow is removed
+ o.EapolFlowReceived = false
+ o.DhcpFlowReceived = false
+ }
+}
+
// HexDecode converts the hex encoding to binary
func HexDecode(pkt []byte) []byte {
p := make([]byte, len(pkt)/2)
@@ -964,12 +1001,12 @@
// In the same way we can create a GemPort even without setting up UNIs/TConts/...
// but we need the GemPort to trigger the state change
- if !o.HasGemPort {
+ if !o.GemPortAdded {
// NOTE this sends a CreateRequestType and BBSim replies with a CreateResponseType
// thus we send this request only once
gemReq, _ := omcilib.CreateGemPortRequest(o.getNextTid(false))
sendOmciMsg(gemReq, o.PonPortID, o.ID, o.SerialNumber, "CreateGemPortRequest", client)
- o.HasGemPort = true
+ o.GemPortAdded = true
} else {
if err := o.InternalState.Event("send_eapol_flow"); err != nil {
onuLogger.WithFields(log.Fields{