Avoid bounce in the ONU State
Retry EAPOL until done
Change-Id: I062e3831905ad27d756a11b147593f4a55051f55
diff --git a/core/eapol.go b/core/eapol.go
index cc9f24c..7e465b3 100644
--- a/core/eapol.go
+++ b/core/eapol.go
@@ -22,8 +22,10 @@
"encoding/hex"
"errors"
"fmt"
+ log "github.com/sirupsen/logrus"
"net"
"sync"
+ "time"
"gerrit.opencord.org/voltha-bbsim/common/logger"
"github.com/google/gopacket"
@@ -40,6 +42,10 @@
EAP_SUCCESS
)
+func (eap clientState) String() string {
+ return [...]string{"EAP_START", "EAP_RESPID", "EAP_RESPCHA", "EAP_SUCCESS"}[eap]
+}
+
type eapResponder struct {
clients map[clientKey]*eapClientInstance
eapolIn chan *byteMsg
@@ -89,11 +95,13 @@
responder := getEAPResponder()
clients := responder.clients
if c, ok := clients[clientKey{intfid: msg.IntfId, onuid: msg.OnuId}]; ok {
- logger.Debug("Got client intfid:%d onuid: %d", c.key.intfid, c.key.onuid)
+ logger.Debug("Got client intfid:%d onuid: %d (ClientID: %v)", c.key.intfid, c.key.onuid, c.curId)
nextstate := respondMessage("EAPOL", *c, msg, eapolIn)
c.updateState(nextstate)
} else {
- logger.Error("Failed to find eapol client instance intfid:%d onuid:%d", msg.IntfId, msg.OnuId)
+ logger.WithFields(log.Fields{
+ "clients": clients,
+ }).Errorf("Failed to find eapol client instance intfid:%d onuid:%d", msg.IntfId, msg.OnuId)
}
case <-ctx.Done():
return
@@ -123,6 +131,37 @@
return nextstate
}
+func sendEAPStart(intfid uint32, onuid uint32, client eapClientInstance, bytes []byte, eapolIn chan *byteMsg) error {
+ for {
+ responder := getEAPResponder()
+ clients := responder.clients
+ if c, ok := clients[clientKey{intfid: intfid, onuid: onuid}]; ok {
+ if c.curState == EAP_SUCCESS {
+ logger.WithFields(log.Fields{
+ "int_id": intfid,
+ "onu_id": onuid,
+ }).Debug("EAP_SUCCESS received, stop retrying")
+ break
+ }
+ } else {
+ logger.WithFields(log.Fields{
+ "clients": clients,
+ }).Errorf("Failed to find eapol client instance intfid:%d onuid:%d (sendEAPStart)", intfid, onuid)
+ }
+ if err := sendBytes(clientKey{intfid, onuid}, bytes, eapolIn); err != nil {
+ return errors.New("Failed to send EAPStart")
+ }
+ logger.WithFields(log.Fields{
+ "int_id": intfid,
+ "onu_id": onuid,
+ "eapolIn": eapolIn,
+ "bytes": bytes,
+ }).Debug("EAPStart Sent")
+ time.Sleep(30 * time.Second)
+ }
+ return nil
+}
+
func startEAPClient(intfid uint32, onuid uint32) error {
client := eapClientInstance{key: clientKey{intfid: intfid, onuid: onuid},
srcaddr: &net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, 0x07, byte(onuid)},
@@ -134,10 +173,8 @@
bytes := client.createEAPOL(eap)
resp := getEAPResponder()
eapolIn := resp.eapolIn
- if err := sendBytes(clientKey{intfid, onuid}, bytes, eapolIn); err != nil {
- return errors.New("Failed to send EAPStart")
- }
- logger.Debug("Sending EAPStart")
+ // start a loop that keeps sending EAPOL packets until it succeeds
+ go sendEAPStart(intfid, onuid, client, bytes, eapolIn)
// clients[key{intfid: intfid, onuid: onuid}] = &client
resp.clients[clientKey{intfid: intfid, onuid: onuid}] = &client
return nil
@@ -156,6 +193,7 @@
if cur == EAP_START {
reseap := c.createEAPResID()
pkt := c.createEAPOL(reseap)
+ logger.Debug("Moving from EAP_START to EAP_RESPID")
return EAP_RESPID, pkt, nil
}
} else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeOTP {
@@ -167,12 +205,14 @@
senddata = append([]byte{0x10}, senddata...)
sendeap := c.createEAPResCha(senddata)
pkt := c.createEAPOL(sendeap)
+ logger.Debug("Moving from EAP_RESPID to EAP_RESPCHA")
return EAP_RESPCHA, pkt, nil
}
} else if eap.Code == layers.EAPCodeSuccess && eap.Type == layers.EAPTypeNone {
logger.Debug("Received EAP-Success")
logger.Debug(recvpkt.Dump())
if cur == EAP_RESPCHA {
+ logger.Debug("Moving from EAP_RESPCHA to EAP_SUCCESS")
return EAP_SUCCESS, nil, nil
}
} else {